Python:当列表仅在运行时确定时,如何将可迭代列表传递给 zip?

Posted

技术标签:

【中文标题】Python:当列表仅在运行时确定时,如何将可迭代列表传递给 zip?【英文标题】:Python: How to pass a list of iterables to zip when the list is only determined at runtime? 【发布时间】:2020-05-28 21:37:29 【问题描述】:

我想使用 zip 以锁步方式迭代各种生成器的元素。只有在运行时才能知道哪些生成器以及它们中有多少。 但是,我不知道如何将其传递给 zip,因为任何列表都将被解释为可迭代对象,而不是必须同时迭代的可迭代对象列表。

这样做的正确方法是什么? 此外,当它们的数量直到运行时才知道时,解压输出的正确方法是什么? 以下是我尝试过的

from typing import List

l_1 = [1, 2, 3]
l_10 = [10, 20, 30]
l_100 = [100, 200, 300]

def gen(l_: List):
    for i in l_:
        yield i

# Standard: works fine as expected
for i, j, k in zip(gen(l_1), gen(l_10), gen(l_100)):
    print('i=, j= k='.format(i,j,k))

# List of generators prepared at run time. Does not work
gens = [gen(l_1), gen(l_100)]
receive = [None] * len(gens)
for receive in zip(gens):
    print(receive)

输出是

i=1, j=10 k=100
i=2, j=20 k=200
i=3, j=30 k=300
(<generator object gen at 0x000001C3DB93C258>,)
(<generator object gen at 0x000001C3DB93C620>,)

想要的输出是

i=1, j=10 k=100
i=2, j=20 k=200
i=3, j=30 k=300
[1, 100]
[2, 200]
[3, 300]

如何让 zip 识别出 gens 不是要迭代的可迭代对象,而是必须在锁定步骤中迭代的可迭代对象列表?

【问题讨论】:

【参考方案1】:

这只是一个很小的变化,要将可迭代的列表传递给 zip,您必须使用 * 解压缩它

# List of generators prepared at run time. Does not work
gens = [gen(l_1), gen(l_100)]
receive = [None] * len(gens)
for receive in zip(*gens):
    print(list(receive))

编辑: 由于您希望输出中包含列表,因此我必须将接收显式转换为列表。

【讨论】:

不错。非常感谢。您如何看待接收位?这是一个合理的方法吗?其他方式? 我并没有真正看过那个!我不知道“接收”代表什么。当您使用receive = [None] * len(gens) 时,这是否意味着循环无法正常运行时的备份?因为通过命名你的循环变量receive,你覆盖Nones的列表 另外请记住,循环中的receive 变量将是tuple 类型的不可变列表,如果您需要对其进行操作,则应将其转换为可变的。 (我猜receive = list(receive) 会是个不错的技巧) 是的,receive = [None] * len(gens) 毫无用处。可以安全移除。我在云端机械地声明一个具有正确尺寸的变量来接收 zip 结果。显然,这不会发生,也不需要。我还没有考虑使用 Python... 我无法想象当您已经习惯了这些较低级别的步骤时学习 python 会是什么样子。我对理解初始化/声明/定义变量之间的差异有疑问。我猜 Pythonic 的思维可能会受到限制,但它让我们能够更多地思考整个算法(我必须说是以性能为代价的)

以上是关于Python:当列表仅在运行时确定时,如何将可迭代列表传递给 zip?的主要内容,如果未能解决你的问题,请参考以下文章

python 迭代器生成

python爬虫同时输出两个列表(zip函数)

Python:如何在迭代列表时从列表中删除元素而不跳过未来的迭代

迭代时从Python列表中删除项目[重复]

如何仅在代码第一次运行时在 python 中运行函数?

当结构仅在运行时已知时,将结构从 c++ 传递到 c#