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
,你覆盖None
s的列表
另外请记住,循环中的receive
变量将是tuple
类型的不可变列表,如果您需要对其进行操作,则应将其转换为可变的。 (我猜receive = list(receive)
会是个不错的技巧)
是的,receive = [None] * len(gens)
毫无用处。可以安全移除。我在云端机械地声明一个具有正确尺寸的变量来接收 zip 结果。显然,这不会发生,也不需要。我还没有考虑使用 Python...
我无法想象当您已经习惯了这些较低级别的步骤时学习 python 会是什么样子。我对理解初始化/声明/定义变量之间的差异有疑问。我猜 Pythonic 的思维可能会受到限制,但它让我们能够更多地思考整个算法(我必须说是以性能为代价的)以上是关于Python:当列表仅在运行时确定时,如何将可迭代列表传递给 zip?的主要内容,如果未能解决你的问题,请参考以下文章