在下面的代码中,zip(* res)是什么意思?

问题描述:

下面是艾伦唐尼的一段代码在github上想想贝叶斯书:在下面的代码中,zip(* res)是什么意思?

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) 

整个文件可以在这个网址可以看出:link on Github for this file.

我试图找出什么呢拉链( * res)是否代表最后一行代码?具体来说:

  1. 作为前缀使用“*”做什么?旁边
  2. 是什么zip函数做(*任何东西)

我是新来的Python,所以我可能会问一些明显。我在函数的文档字符串中看到作者的注释,它返回一个(price1 price2 ...)序列,但它对我来说不太明显。

UPDATE:詹姆斯Rettie的前面回答的后续行动,这里是我所得到的,当我跑,他在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。

+0

谢谢为了指点我这个链接。它确实回答了我上面的问题。 – Bharat

+2

对于python 3,使用'list(zip(* x))'。好的是,这将在python 2中起作用,因为将'list'应用于列表仍然会给出相同的列表。 – ImportanceOfBeingErnest

+0

不错!这对我有用。谢谢。 – Bharat

在python中,*是'splat'操作符。它用于将列表解压缩为参数。例如:foo(*[1, 2, 3])foo(1, 2, 3)相同。

zip()函数采用n iterables,并返回y元组,其中y是至少提供的所有iterables的长度的。 y th元组将包含提供的所有迭代的第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)转置矩阵(二维数组/列表)。所述* operator“解包”的矩阵和zip交错的可迭代或行和拉链的行逐列:

> x = [('a', 'b', 'c'), (1, 2, 3)] 
> zip(*x) 
[('a', 1), ('b', 2), ('c', 3)] 

想象镜像对角线上的矩阵。