【问题标题】:what is meaning of [iter(list)]*2 in python?python中[iter(list)] * 2的含义是什么?
【发布时间】:2020-08-23 12:37:07
【问题描述】:

我在网上找到了下面的代码,结果是列表中两个元素的元组,如何理解[iter(list)]*2

lst = [1,2,3,4,5,6,7,8]
b=zip(*[iter(lst)]*2)
list(b)

[(1, 2), (3, 4), (5, 6), (7, 8)]

------------
[iter(lst)]*2
[<list_iterator at 0x1aff33917f0>, <list_iterator at 0x1aff33917f0>]

我检查了[iter(lst)]*2,上面的迭代器相同,所以意思是iter重复双倍, 所以,如果我检查 num 从 2 到 3,结果应该是 [(1, 2, 3), (4, 5, 6),(7,8,NaN)] 但删除 7,8

lst = [1,2,3,4,5,6,7,8]
b=zip(*[iter(lst)]*3)
list(b)
--------------
[(1, 2, 3), (4, 5, 6)]

【问题讨论】:

  • 您尝试过什么,哪些具体部分让您感到困惑?你检查过每一步的输出吗?如检查[iter(lst)] 的输出,然后检查[iter(lst)]*2 等的输出?

标签: python iterator zip


【解决方案1】:

iter(lst) 将列表转换为iterator。迭代器让您可以通过调用 next() 来懒惰地通过一个迭代器,直到迭代器用完所有项。

[iter(lst)] 将迭代器放入一个单元素列表中。

[iter(lst)] * 2 在列表中复制 2 份迭代器,给

it = iter(lst)
[it, it] 

两个列表元素都是同一个底层迭代器对象的别名,所以当zip 耗尽它们时,每当在其中一个迭代器上调用next() 时,都会产生连续的元素。

*[...] 将同一迭代器的两个副本的列表解包到zip 的参数中。这将创建一个 zip 对象,让您可以从其每个参数中迭代元素元组。

list(...) 遍历 zip 对象并将元素复制到列表中。由于两个压缩迭代器都指向同一个底层迭代器,因此我们会在输出中看到顺序元素。

不使用迭代器别名,你会得到 ​​p>

>>> list(zip(iter(lst), iter(lst)))
[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8)]

list(zip(*[iter(lst)] * 2)) 的类似写法是list(zip(lst[::2], lst[1::2])),这似乎没有那么神奇(如果性能低得多的话)。

解释

>>> list(zip(*[iter(lst)] * 3))
[(1, 2, 3), (4, 5, 6)]

省略元素是 zip 对象第一次尝试在任何参数迭代中产生None 结果时,它会停止并且不会生成元组。您可以使用itertools.zip_longest 或多或少地匹配您的预期行为:

>>> list(zip_longest(*[iter(lst)] * 3))
[(1, 2, 3), (4, 5, 6), (7, 8, None)]

如果 [...] * 2 的别名行为令人惊讶,请参阅规范答案 List of lists changes reflected across sublists unexpectedly

【讨论】:

    【解决方案2】:

    解释起来相当棘手。我试一试:

    使用[iter(lst)],您可以创建一个包含一个项目的列表。该项目是列表的迭代器。

    每当python试图从这个迭代器中获取一个元素时,就会返回lst的下一个元素,直到没有更多元素可用为止。

    请尝试以下操作:

    i = iter(lst)
    next(i)
    next(i)
    

    输出应如下所示:

    >>> lst = [1,2,3,4,5,6,7,8]  
    >>> i = iter(lst)
    >>> next(i)
    1
    >>> next(i)
    2
    >>> next(i)
    3
    >>> next(i)
    4
    >>> next(i)
    5
    >>> next(i)
    6
    >>> next(i)
    7
    >>> next(i)
    8
    >>> next(i)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration
    

    现在您创建一个包含两次完全相同迭代器的列表。 你这样做 itlst = [iter(lst)] * 2

    尝试以下:

    itlst1 = [iter(lst)] * 2
    itlst2 = [iter(lst), iter(lst)]
    print(itlst1)
    print(itlst2)
    

    结果将类似于:

    >>> itlst1 = [iter(lst)] * 2
    >>> itlst2 = [iter(lst), iter(lst)]
    >>> print(itlst1)
    [<list_iterator object at 0x7f9251172b00>, <list_iterator object at 0x7f9251172b00>]
    >>> print(itlst2)
    [<list_iterator object at 0x7f9251172b70>, <list_iterator object at 0x7f9251172ba8>]
    

    需要注意的是,itlst1 是一个包含两个相同迭代器的列表,而itlst2 包含两个不同的迭代器。

    为了说明尝试输入:

    next(itlst1[0])
    next(itlst1[1])
    next(itlst1[0])
    next(itlst1[1])
    

    并将其与:

    next(itlst2[0])
    next(itlst2[1])
    next(itlst2[0])
    next(itlst2[1])
    

    结果是:

    >>> next(itlst1[0])
    1
    >>> next(itlst1[1])
    2
    >>> next(itlst1[0])
    3
    >>> next(itlst1[1])
    4
    >>> 
    >>> next(itlst2[0])
    1
    >>> next(itlst2[1])
    1
    >>> next(itlst2[0])
    2
    >>> next(itlst2[1])
    2
    

    现在到zip() 函数(https://docs.python.org/3/library/functions.html#zip):

    尝试以下操作:

    i = iter(lst)
    list(zip(i, i))
    

    zip() 有两个参数。 每当您尝试从 zip 获取下一个元素时,它将执行以下操作:

    • 从作为第一个参数的可迭代对象中获取一个值
    • 从第二个参数的迭代中获取一个值
    • 返回一个包含这两个值的元组。

    list(zip(xxx)) 将重复执行此操作并将结果存储在列表中。

    结果将是:

    >>> i = iter(lst)
    >>> list(zip(i, i))
    [(1, 2), (3, 4), (5, 6), (7, 8)]
    

    使用的下一个技巧是*,它用于将第一个元素用作函数调用的第一个参数,将第二个元素用作第二个参数,依此类推)What does ** (double star/asterisk) and * (star/asterisk) do for parameters?

    这么写:

    itlst1 = [iter(lst)] * 2
    list(zip(*itlst1))
    

    在这种情况下与

    相同
    i = iter(lst)
    itlst1 = [i] * 2
    list(zip(itlst1[0], itlst1[1]))
    

    相同
    list(zip(i, i))
    

    我已经解释过了。

    希望这可以解释上述大部分技巧。

    【讨论】:

    • 解释得很好!
    • 真的很棒的工作。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2022-07-21
    • 1970-01-01
    • 1970-01-01
    • 2017-01-05
    • 2021-05-13
    • 1970-01-01
    • 2011-11-08
    • 2017-11-21
    相关资源
    最近更新 更多