Python 在zip函数之前使用星号

Python 在zip函数之前使用星号,python,numpy,Python,Numpy,下面的代码来自Jake VanderPlas的书《Python数据科学手册》: 有几个问题: 我见过在zip函数中使用星号来解包元组,但没有见过在zip这样的函数调用之前使用星号。以这种方式理解星号的正确用法是什么 为了试图了解发生了什么,我查看了print(*zip(X[j],X[I])的结果似乎每个点的X&Y坐标都被解包并压缩在一起,这样就有了两个元组。为什么这是正确的逻辑?还有,理解plot函数如何处理/解释每对元组的正确方法是什么?我从未见过一对元组以这种方式传递到plot函数n 函数调

下面的代码来自Jake VanderPlas的书《Python数据科学手册》:

有几个问题:

  • 我见过在zip函数中使用星号来解包元组,但没有见过在zip这样的函数调用之前使用星号。以这种方式理解星号的正确用法是什么
  • 为了试图了解发生了什么,我查看了
    print(*zip(X[j],X[I])的结果
    似乎每个点的X&Y坐标都被解包并压缩在一起,这样就有了两个元组。为什么这是正确的逻辑?还有,理解plot函数如何处理/解释每对元组的正确方法是什么?我从未见过一对元组以这种方式传递到plot函数n

  • 函数调用中的
    *
    将列表(或其他iterable)转换为
    *args
    类型的参数

    zip
    带有多个列表,通过它们对元素进行迭代:

    In [1]: list(zip([1,2,3],[4,5,6]))
    Out[1]: [(1, 4), (2, 5), (3, 6)]
    
    如果我们定义一个列表:

    In [2]: alist = [[1,2,3],[4,5,6]]
    In [3]: list(zip(alist))
    Out[3]: [([1, 2, 3],), ([4, 5, 6],)]
    
    那张
    zip
    没有什么作用。但是如果我们把它作为明星:

    In [4]: list(zip(*alist))
    Out[4]: [(1, 4), (2, 5), (3, 6)]
    
    检查
    zip
    文档-参见
    *args

    In [5]: zip?
    Init signature: zip(self, /, *args, **kwargs)
    Docstring:     
    zip(*iterables) --> A zip object yielding tuples until an input is exhausted.
    
       >>> list(zip('abcdefg', range(3), range(4)))
       [('a', 0, 0), ('b', 1, 1), ('c', 2, 2)]
    
    The zip object yields n-length tuples, where n is the number of iterables
    passed as positional arguments to zip().  The i-th element in every tuple
    comes from the i-th iterable argument to zip().  This continues until the
    shortest argument is exhausted.
    Type:           type
    Subclasses:  
    
    *
    也可以与类似
    def foo(arg1、arg2、arg3)的函数一起使用:…

    plt.plot(*zip(X[j],X[i]),color='black')
    中,
    plot
    具有类似
    plot(X,y,kwargs)
    的签名。我认为这与

    plt.plot(X[j], X[i], color='black')
    
    但我必须测试一些代码

    编辑
    list(*zip(…)
    是矩阵转置的列表版本。

    考虑两点,
    a
    b

    a=[1,2]
    b=[3,4]
    
    当我们拉上拉链时,我们得到:

    print(list(zip(a,b))#[1,3],[2,4]]
    
    我们可以看到,每个元素的第一个元素是成对的,每个元素的第二个元素也是如此。这就是zip的工作原理;我怀疑这对您来说是有意义的。如果这些是(x,y)点,那么我们只是将x和y分组在一起

    现在,考虑<代码> PLT。图(x,y,…)< /代码>。它期望第一个参数都是x的,第二个参数都是y的。嗯,zip只为我们组合在一起。我们可以使用<代码> */Cuth>运算符来扩展前两个参数。注意这些是等价的操作:

    p=list(zip(a,b))
    plt.绘图(*p)
    plt.图(p[0],p[1])
    
    旁注:要扩展到更多点,我们只需将额外的点添加到zip中:

    a=[1,2]
    b=[3,4]
    c=[5,6]
    打印(列表(zip(a,b,c))#[1,3,5],[2,4,6]]
    plt.plot(*zip(a,b,c))#绘制3个点
    
    它是不同的;
    X[i]
    是一个
    (X,y)
    元组,但绘图需要所有X和所有y一起。实际上,
    *zip()
    是矩阵转置的列表/元组形式。请参阅我的编辑,它使用一个简单的打印函数进行测试。您的示例精确地显示了
    plt.plot(X[j],X[i])
    plt.plot(*zip(X[j],X[i]))
    是不同的……它用于任何生成器/iterable,而不仅仅是zip。它将类似列表的对象解压到单个条目中。我个人一直使用它来打印字符串列表:例如
    print(*string\u list,sep='\n')
    plt.plot(X[j], X[i], color='black')
    
    def foo(x,y):
        print(x,y)
    
    In [11]: X = np.arange(10).reshape(5,2)
    In [12]: foo(X[1],X[0])
    [2 3] [0 1]
    In [13]: foo(*zip(X[1],X[0]))
    (2, 0) (3, 1)