这是艾伦·唐尼(Allen Downey(的《思想贝叶斯》(Think Bayes book(的一块代码:
def ReadData(filename='showcases.2011.csv'):
"""Reads a CSV file of data.
Args:
filename: string filename
Returns: sequence of (price1 price2 bid1 bid2 diff1 diff2) tuples
"""
fp = open(filename)
reader = csv.reader(fp)
res = []
for t in reader:
_heading = t[0]
data = t[1:]
try:
data = [int(x) for x in data]
# print heading, data[0], len(data)
res.append(data)
except ValueError:
pass
fp.close()
return zip(*res)
可以在此文件的github上的link上看到整个文件。
我试图弄清Zip(*res(在最后一行的代码上意味着什么?具体:
- 当用作前缀时,一个'*'会做什么。下一个
- zip函数对(*nothing( 有什么作用
我是Python的新手,所以我可能会问一些明显的事情。我在函数的Docstring中看到了作者的注释,它返回了一组(Price1 Price2 ...(,但对我来说还不清楚。
更新:跟进James Rettie的Anwer,这是我在Python 3.6中提供的代码时得到的:
In [51]: zip(['a', 'b', 'c'], [1, 2, 3])
Out[51]: <zip at 0x1118af848>
虽然在Python 2.7中运行相同的代码可产生他提供的结果,如下所示:
In [2]: zip(['a', 'b', 'c'], [1, 2, 3])
Out[2]: [('a', 1), ('b', 2), ('c', 3)]
你能解释为什么吗?区别是Python 2.7,Python 3.6对我来说很重要,因为我仍然必须支持Python 2.7,但我想搬到3.6。
在python中, *是'splat'操作员。它用于将列表解开为参数。例如:foo(*[1, 2, 3])
与foo(1, 2, 3)
相同。
zip()
功能采用n
迭代物,并返回y
元组,其中y是提供的所有迭代的最小值。y
元组将包含提供的所有迭代元素的y
元素。
例如:
zip(['a', 'b', 'c'], [1, 2, 3])
将产生
('a', 1) ('b', 2) ('c', 3)
对于您提供的示例中的res
嵌套列表,调用zip(*res)
将做类似的事情:
res = [['a', 'b', 'c'], [1, 2, 3]]
zip(*res)
# this is the same as calling zip(['a', 'b', 'c'], [1, 2, 3])
('a', 1)
('b', 2)
('c', 3)
zip(*res)
转置矩阵(2-D数组/列表(。*
操作员"解开"矩阵和zip
的迭代或行交织,然后将行列为行:
> x = [('a', 'b', 'c'), (1, 2, 3)]
> zip(*x)
[('a', 1), ('b', 2), ('c', 3)]
想象一下对角线上的矩阵。