同じfor
ループに2つの変数を含めるにはどうすればいいですか?
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)):
...
ネストされたforループの効果が必要な場合は、次を使用します。
import itertools
for i, j in itertools.product(range(x), range(y)):
# Stuff...
同時にループするだけの場合は、次を使用します。
for i, j in Zip(range(x), range(y)):
# Stuff...
x
とy
の長さが同じでない場合、Zip
は最も短いリストに切り捨てられることに注意してください。 @abarnertが指摘したように、最短のリストに切り捨てたくない場合は、itertools.Zip_longest
を使用できます。
UPDATE
「リスト「t1」と「t2」を読み取り、同一のすべての要素を返す関数」の要求に基づいて、OPはZip
orproduct
。私は彼らがset
を望んでいると思う:
def equal_elements(t1, t2):
return list(set(t1).intersection(set(t2)))
# You could also do
# return list(set(t1) & set(t2))
intersection
のset
メソッドは、それに共通するすべての要素と別のセットを返します(リストに他のlist
sが含まれている場合は、最初に内部のlist
sをtuples
に変換してハッシュ可能にするか、そうでない場合はset
を呼び出します失敗します。)。 list
関数は、セットをリストに戻します。
更新2
または、OPはリスト内の同じ位置で同一の要素を必要とする場合があります。この場合、Zip
が最も適切であり、最短のリストに切り捨てられるという事実が必要です(リストの1つが5要素のみの場合、インデックス9に同じ要素が存在することは不可能であるため) )。それがあなたが望むものであるならば、これで行ってください:
def equal_elements(t1, t2):
return [x for x, y in Zip(t1, t2) if x == y]
これにより、リスト内の同じ位置にある同じ要素のみを含むリストが返されます。
ここで考えられる質問が2つあります。それらの変数をどのように反復することができますか同時に、またはどのようにそれらの変数をループ処理することができます組み合わせ。
幸い、両方に簡単な答えがあります。最初のケースでは、あなたはZip
を使いたいのです。
x = [1, 2, 3]
y = [4, 5, 6]
for i, j in Zip(x, y):
print i + " / " + j
出力します
1 / 4
2 / 5
3 / 6
Zip
にany iterableを入れることができることを忘れないでください。そのため、以下のように簡単に例を書くことができます。
for i, j in Zip(range(x), range(y)):
# do work here.
実際には、うまくいかないことに気づいただけです。小さい範囲がなくなるまで繰り返します。その場合は、ループの組み合わせを反復処理したいようです。
それ以外の場合は、ネストループが必要です。
for i in x:
for j in y:
print i + " / " + j
あなたにあげる
1 / 4
1 / 5
1 / 6
2 / 4
2 / 5
...
リスト内包としてこれを行うこともできます。
[i + " / " + j for i in range(x) for j in range(y)]
それが役立つことを願っています。
入れ子になったforループを使えない理由は何ですか?
for i in range(x):
for j in range(y):
#code that uses i and j
for (i,j) in [(i,j) for i in range(x) for j in range(y)]
それをするべきです。
ある範囲で本当にロックステップの反復があるだけなら、いくつかの方法のうちの1つを実行できます。
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)):
…
x <= y
の場合、上記のすべてはfor i, j in Zip(range(x), range(y))
と同等です。
ネストループが必要で、2つのイテラブルしかない場合は、ネストループを使用してください。
for i in range(x):
for i in range(y):
…
3つ以上のイテラブルがある場合は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')
…
「Python 3」
Zipとrangeを使用してforループを2つ追加します。リストを返す.
注:最小範囲の終わりまでしか実行されません。
>>>a=[g+h for g,h in Zip(range(10), range(10))]
>>>a
>>>[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
入れ子になったループを探していると思います。
例(あなたの編集に基づく):
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
あなたのユースケースでは、 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
注意点として、このアプローチはあなたの最短リストの長さに切り捨てられます。