大道至简:Python奇技淫巧记录 | 语法糖分析

发布时间 2023-04-14 15:55:05作者: izcat

0. 内置函数 enumerate

偶然看到别人题解中 for i, item in enumerate(arr)的写法,非常方便。
在需要获取元素index而又不关心数组长度情况下,推荐这种写法,节省了两行代码!
否则:

n = len(arr)
for i in range(n):
   item = arr[i]
   pass

# 或者
i = 0
for item in arr:
   pass
   i += 1

参考Python enumerate() 函数 | 菜鸟教程 (runoob.com),该函数输入为可迭代对象,可选第二个参数为开始下标位置,默认为0。

1. zip妙用

类似于map函数,内置函数zip将一组可迭代对象按每个元素顺序打包,返回元组的可迭代类型/列表。
一般配合符号 * 使用,将列表解压,可以理解为去掉了外层括号,将多个元素作为不定长参数。
二维矩阵转置:

a = [[1,2,3],[4,5,6]]
a_T = list(zip(*a)) # [(1, 4), (2, 5), (3, 6)]

2. Python传参

写这道题1268. 搜索推荐系统碰到一个问题,需要部分搜索,返回前缀相同的字典序最小的三个字符串。

要求字典序最小,构建了字典树后,使用DFS即可。因为只要最多3个,常规做法就是维护全局变量,记录已经找到的答案。

查看原始DFS写法

   # 全局变量
   cnt = 3  # 还需要找的数量
   now = [] # 已找到的字符串
   def find(p, pre=''):
       # 从p位置开始找3个
       nonlocal now, cnt
       if 'isEnd' in p:
           now.append(pre)
           cnt -= 1
       for x in sorted(p.keys()):
           if cnt==0:
               break
           if x!='isEnd':
               find(p[x], pre+x)
   
   

研究发现,Python传递的可变参数,如list,dict类型其实都是引用,因此可以将全局变量传参进去,这样会使代码更加简洁。

def change(arr, i=1):
   	arr.append(i)
   	if len(arr)<10:
   		change(arr, i+1)
   
arr = []
change(arr)
print(arr) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
查看修改后DFS写法

   def find(p, pre, now):
       # 从p位置开始找3个
       if 'isEnd' in p:
           now.append(pre)
       if len(now)==3:
           return
       for x in sorted(p.keys()):
        if len(now)==3:
               break
           find(p[x], pre+x, now)