【问题标题】:Python: Loops for simultaneous operation, Two or possibly more?Python:同时操作的循环,两个或更多?
【发布时间】:2013-05-14 20:45:29
【问题描述】:

这个问题与How do I run two python loops concurrently?密切相关

我会以更清晰的方式表达: 我得到了提问者在上面的链接中提出的问题,比如

for i in [1,2,3], j in [3,2,1]:
    print i,j
    cmp(i,j) #do_something(i,j)

但是

L1:对于 [1,2,3] 中的 i 和 [3,2,1] 中的 j: 不工作

第一季度。 但这很有趣:

    for i in [1,2,3], j in [3,2,1]:
    print i,j


[1, 2, 3] 0
False 0

第二季度。如何让 L1 之类的东西发挥作用?

真的不是多线程或并行。 (是两个并发任务,不是一个循环里面的一个循环)然后比较两者的结果。

这里的列表是数字。我的情况不是数字:

for i in f_iterate1() and j in f_iterate2():

更新:下面的 abarnert 是对的,我在某处定义了 j。所以现在是:

>>> for i in [1,2,3], j in [3,2,1]:
    print i,j



Traceback (most recent call last):
  File "<pyshell#142>", line 1, in <module>
    for i in [1,2,3], j in [3,2,1]:
NameError: name 'j' is not defined

而且我不想压缩两个迭代函数!但是在类似 for 循环的情况下同时处理它们。问题仍然存在,如何在 python 中实现。

更新 #2:解决相同长度的列表

>>> def a(num):
    for x in num:
        yield x


>>> n1=[1,2,3,4]
>>> n2=[3,4,5,6]
>>> x1=a(n1)
>>> x2=a(n2)
>>> for i,j in zip(x1,x2):
    print i,j


1 3
2 4
3 5
4 6
>>> 

[已解决]

第三季度。如果 n3=[3,4,5,6,7,8,78,34] 大于 n1,n2 怎么办。 zip 在这里不起作用。像 izip_longest 之类的东西? izip_longest 足够好。

【问题讨论】:

  • 在您编辑之后,我完全不明白您在问什么。两个答案都向您展示了如何同时处理它们。在for 循环的每次迭代中,每个迭代器都有一个值,您可以在同一个表达式中一起使用它们。正是你想用你的“L1”做什么。那么……您要解决的进一步问题是什么?
  • 至于更新的其他部分......你不明白为什么你会在这里得到一个NameError,或者为什么你在定义j 时得到你之前的输出?
  • 你能显示你想从给定的输入中得到什么输出吗?我们不明白你想要达到什么目的。
  • 是的,izip_longest() 将在一个列表较长时为您工作。我已经在回答中提到了这一点。 :-)
  • @abarnert NameError 问题现已解决。基本上,类似于 :: for x in process_1 和 y in process_2: do_something(with x & y)。现在如果进程(生成器)增加,迭代器也会增加并且 do_something(with x,y,...n)

标签: python for-loop


【解决方案1】:

很难理解你在问什么,但我想你只想zip

for i, j in zip([1,2,3], [3,2,1]):
    print i, j

for i, j in zip(f_iterate1(), f_iterate2()):
    print i, j

等等……

这不会同时做任何事情,因为该术语通常被使用,它一次只做一件事,但那一件事是“在锁定步骤中迭代两个序列”。


请注意,这显然会扩展到三个或更多列表:

for i, j, k in zip([1,2,3], [3,2,1], [13, 22, 31]):
    print i, j, k

(如果您甚至不知道您有多少个列表,请查看 cmets。)


如果您想知道这是怎么回事:

for i in [1,2,3], j in [3,2,1]:
    print i,j

试试这个:

print [1,2,3], j in [3,2,1]

如果您已经在某处定义了j,它将打印[1, 2, 3] False[1, 2, 3] True。否则,您将获得NameError。那是因为您只是创建了一个包含两个值的元组,第一个是列表 [1,2,3],第二个是表达式 j in [3,2,1] 的结果。

所以:

j=0
for i in [1,2,3], j in [3,2 1]:
    print i, j

…等价于:

j=0
for i in ([1,2,3], False):
    print i, 0

…这将打印:

[1, 2, 3] 0
False 0

【讨论】:

  • 对于多个列表是否值得注意* 运算符?
  • @squiguy:你是说zip(*list_of_lists)?我认为这只会混淆这个问题。如果您知道要迭代多少个值,那么您就知道要压缩多少个列表。如果你也不知道,你必须写for tuple_of_values in zip(*list_of_lists) 什么的。但也许 值得一提的是,zip 适用于超过 2 个值。
  • 是的,完全正确。这超出了确切问题的范围,但可能值得注意......在其他时间可能会有所帮助。
  • @squiguy:我赞成你的评论,并在答案中引用它;希望这能给它恰到好处的焦点?
  • @squiguy 我认为 zip(*list_of_lists) 解决了这个问题。如果 abarnet 建议使用 zip,我正在尝试使用生成器。
【解决方案2】:

你想使用zip() function:

for i, j in zip([1, 2, 3], [3, 2, 1]):
    #

for i, j in zip(f_iterate1(), f_iterate2()):
    #

zip() 将输入列表的元素配对,让您一起处理它们。

如果您的输入很大或者是迭代器,请使用 future_builtins.zip(),或者,如果您不关心与 Python 3 的前向兼容性,请改用 itertools.izip();这些按需生成对,而不是一次性创建整个输出列表:

from future_builtins import zip

for i, j in zip(f_iterate1(), f_iterate2()):

您的生成器属于这种情况。

最后但同样重要的是,如果您的输入列表有不同的长度,zip() 会在最短的列表用完时停止。如果您想继续使用 最长 列表,请使用 itertools.izip_longest();当较短的输入序列用尽时,它将使用填充值:

>>> for i, j, k in izip_longest(range(3), range(3, 5), range(5, 10), fillvalue=42):
...     print i, j, k
... 
0 3 5
1 4 6
2 42 7
42 42 8
42 42 9

fillvalue 的默认值为 None


你的尝试:

for i in [1,2,3], j in [3,2,1]:

实际上解释为:

for i in ([1,2,3], j in [3,2,1]):

其中后一部分被解释为具有两个值的元组,一个是列表,另一个是布尔值;在测试j in [3,2,1] 之后,是TrueFalse。您将j 定义为之前循环实验中的0,因此0 in [3, 2, 1]False

【讨论】:

  • @Martjin 是的,这就是我想要的。有效。我为此添加了更新#2,其中包含示例代码,同时使用 izip_longest 对其进行测试。
【解决方案3】:

对于相同长度的数组,可以使用索引来引用各个列表中的对应位置,如下所示:

a = [1, 2, 3, 4, 5]
b = [2, 4, 6, 8, 10]
for i in range(len(a)):
    print(a[i])
    print(b[i])

这会同时访问两个列表的相同索引。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-09
    • 1970-01-01
    • 2018-04-05
    • 1970-01-01
    • 2014-10-14
    • 1970-01-01
    • 1970-01-01
    • 2011-03-29
    相关资源
    最近更新 更多