关于功能:在下面的代码中,zip(* res)在python中的含义是什么?

what does zip(*res) mean in python in the following code?

本问题已经有最佳答案,请猛点这里访问。

以下是AllenDowney的ThinkBayes在Github上的一段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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上的url:link上看到。

我想知道在最后一行代码中,zip(*res)是什么意思?明确地:

  • 当用作前缀时"*"的作用是什么?下一个
  • Zip函数对(*有什么作用)
  • 我对python不熟悉,所以我可能会问一些明显的问题。我在函数的docstring中看到作者的注释,它返回一个(price1 price2…)序列,但我不太清楚。

    更新:下面是对JamesRettie的Anwer的跟踪,下面是我在运行他在Python3.6中提供的代码时得到的信息:

    1
    2
    In [51]: zip(['a', 'b', 'c'], [1, 2, 3])
    Out[51]: <zip at 0x1118af848>

    而在python 2.7中运行相同的代码会产生如下所示的结果:

    1
    2
    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()函数接受niterables,并返回y元组,其中y是所提供的所有iterables长度中最小的一个。yth元组将包含所提供的所有iterables的yth元素。

    例如:

    1
    zip(['a', 'b', 'c'], [1, 2, 3])

    将屈服

    1
    ('a', 1) ('b', 2) ('c', 3)

    对于像您提供的示例中的res这样的嵌套列表,调用zip(*res)将执行如下操作:

    1
    2
    3
    4
    5
    6
    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)转换矩阵(二维数组/列表)。*运算符"解包"一个或多个矩阵行,zip交错并沿列压缩行:

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

    想象一下在对角线上镜像矩阵。