昨天在刷 LeetCode 题目的时候学到一个很骚的 Python 操作,就是 itertools 以及 Python 中 * 星号的作用,专业术语叫做解包。花了一些时间搜索才搜到正确的解读,于是在此记录一下。Python 中 itertools.product(*args) 这个工具确实是非常好用,不过一般来说我们可能也不怎么会用到,但是还是可以了解一下。
以下为转载,原文地址:https://blog.csdn.net/AlanGuoo/article/details/78865493
一、Python itertools.product() 操作
目前有一字符串 s = "['a', 'b'],['c', 'd']"
,想把它分开成为两个列表:
list1 = ['a', 'b'] list2 = ['c', 'd']
之后使用 itertools.product()
求笛卡尔积,应该写成:
for i in itertools.product(list1, list2): print i
结果为:
('a', 'c') ('a', 'd') ('b', 'c') ('b', 'd')
然而使用 eval(s)
获得的是一个元组。product
的参数如果是元组则一定会报错(product
的参数是两个列表,每个列表中的元素数量不定)。怎么破?
二、Python 星号 * 解包技巧
其实只差一个 *
而已。*
是 Python 中一个赋值的技巧,叫做解包。相信很多人都见过 def func(*args, **kwargs)
这种写法,在函数中,*
代表不定个数的参数,以 tuple
的方式传入,**
则是以 dict
的方式。在使用函数的时候,也可以有类似的方法,调用 func(*args)
函数时,相当于把一个元组 args
拆开,当成参数传进函数中。只是这样做要小心的是,args
中含有的元素数量及类型必须跟该函数定义一致,否则会报 SyntaxError: invalid syntax
语法错误。
例如,在这道题中,就可以写成:
for i in itertools.product(*eval(s)): print i
就可以出来结果了。
这个问题用到的三个技巧:
itertools.product()
求笛卡尔积。itertools
这个模块中有相当多的牛逼闪闪的数学算法,比如全排列函数permutations
,组合函数combinations
等等,有时候想要一个数学类的函数又不想自己写,可以在这里找找,没准有惊喜。eval()
字符串求值。eval
和exec
这两个 Python 中的逆天函数,强大到让人不太放心其安全性。*
解包。上面已经解释过了,其实用到的场合感觉挺有限的,有印象即可,能在无路可走的时候灵光一现就好,别太指望它给你的程序带来多大好处。