151

如何在同一个for循环中包含两个变量?

t1 = [a list of integers, strings and lists]
t2 = [another list of integers, strings and lists]

def f(t):  #a function that will read lists "t1" and "t2" and return all elements that are identical
    for i in range(len(t1)) and for j in range(len(t2)):
        ...
4

8 回答 8

239

如果您想要嵌套 for 循环的效果,请使用:

import itertools
for i, j in itertools.product(range(x), range(y)):
    # Stuff...

如果您只想同时循环,请使用:

for i, j in zip(range(x), range(y)):
    # Stuff...

注意如果xy长度不一样,zip会截断到最短的列表。正如@abarnert 指出的那样,如果您不想截断到最短的列表,您可以使用itertools.zip_longest.

更新

根据对“将读取列表“t1”和“t2”并返回所有相同元素的函数的请求,我认为 OP 不想要zip or product。我认为他们想要一个set

def equal_elements(t1, t2):
    return list(set(t1).intersection(set(t2)))
    # You could also do
    # return list(set(t1) & set(t2))

a的intersection方法set将返回它和另一个集合共有的所有元素(请注意,如果您的列表包含其他lists,您可能希望将内部lists 转换为tuplesfirst 以便它们是可散列的;否则调用set将失败。)。然后该list函数将集合转回列表。

更新 2

或者,OP 可能需要列表中相同位置的相同元素。在这种情况下,zip这将是最合适的,并且它截断为最短列表的事实是您想要的(因为当列表之一只有 5 个元素长时,索引 9 处不可能有相同的元素) . 如果这是您想要的,请执行以下操作:

def equal_elements(t1, t2):
    return [x for x, y in zip(t1, t2) if x == y]

这将返回一个列表,其中仅包含列表中相同且位于相同位置的元素。

于 2013-09-06T01:55:29.673 回答
89

这里有两个可能的问题:如何同时迭代这些变量,或者如何循环它们的组合

幸运的是,两者都有简单的答案。第一种情况,您想使用zip.

x = [1, 2, 3]
y = [4, 5, 6]

for i, j in zip(x, y):
   print(str(i) + " / " + str(j))

将输出

1 / 4
2 / 5
3 / 6

请记住,您可以将任何可迭代对象放入 中zip,因此您可以像这样轻松编写示例:

for i, j in zip(range(x), range(y)):
    # do work here.

实际上,刚刚意识到这行不通。它只会迭代直到较小的范围用完。在这种情况下,听起来您想迭代循环的组合。

在另一种情况下,您只需要一个嵌套循环。

for i in x:
    for j in y:
        print(str(i) + " / " + str(j))

给你

1 / 4
1 / 5
1 / 6
2 / 4
2 / 5
...

您也可以将其作为列表理解来执行。

[str(i) + " / " + str(j) for i in range(x) for j in range(y)]

希望有帮助。

于 2013-09-06T02:00:07.960 回答
21

有什么理由不能使用嵌套的 for 循环?

for i in range(x):
   for j in range(y):
       #code that uses i and j
于 2013-09-06T01:52:13.283 回答
15
for (i,j) in [(i,j) for i in range(x) for j in range(y)]

应该这样做。

于 2013-09-06T01:51:29.613 回答
9

如果您真的只是在一个范围内进行锁步迭代,您可以通过以下几种方式之一进行:

for i in range(x):
  j = i
  …
# or
for i, j in enumerate(range(x)):
  …
# or
for i, j in ((i,i) for i in range(x)):
  …

以上都等价于for i, j in zip(range(x), range(y))if x <= y

如果你想要一个嵌套循环并且你只有两个迭代,只需使用一个嵌套循环:

for i in range(x):
  for i in range(y):
    …

如果您有两个以上的可迭代对象,请使用itertools.product.

最后,如果您想要锁步迭代直到x然后继续到y,您必须决定其余的x值应该是什么。

for i, j in itertools.zip_longest(range(x), range(y), fillvalue=float('nan')):
  …
# or
for i in range(min(x,y)):
  j = i
  …
for i in range(min(x,y), max(x,y)):
  j = float('nan')
  …
于 2013-09-06T02:22:06.913 回答
8

“Python 3。”

使用 zip 和 range 添加 2 个带有 for 循环的变量;返回一个列表。

注意:只会运行到最小范围结束。

>>>a=[g+h for g,h in zip(range(10), range(10))]
>>>a
>>>[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
于 2017-07-04T17:29:24.337 回答
6

while对于您的用例,使用循环可能更容易。

t1 = [137, 42]
t2 = ["Hello", "world"]

i = 0
j = 0
while i < len(t1) and j < len(t2):
    print t1[i], t2[j]
    i += 1
    j += 1

# 137 Hello
# 42 world

需要注意的是,这种方法将截断到最短列表的长度。

于 2018-04-28T02:57:38.120 回答
3

我认为您正在寻找嵌套循环。

示例(基于您的编辑):

t1=[1,2,'Hello',(1,2),999,1.23]
t2=[1,'Hello',(1,2),999]

t3=[]

for it1, e1 in enumerate(t1):
    for it2, e2 in enumerate(t2):
        if e1==e2:
            t3.append((it1,it2,e1))

# t3=[(0, 0, 1), (2, 1, 'Hello'), (3, 2, (1, 2)), (4, 3, 999)]

这可以简化为一个单一的理解:

[(it1,it2,e1) for it1, e1 in enumerate(t1) for it2, e2 in enumerate(t2) if e1==e2] 

但是要找到共同的元素,你可以这样做:

print set(t1) & set(t2)
# set([(1, 2), 1, 'Hello', 999])

如果您的列表包含不可散列的对象(如其他列表、字典),请使用冻结集:

from collections import Iterable
s1=set(frozenset(e1) if isinstance(e1,Iterable) else e1 for e1 in t1)
s2=set(frozenset(e2) if isinstance(e2,Iterable) else e2 for e2 in t2)
print s1 & s2
于 2013-09-06T02:26:51.240 回答