セットを使用して、タプルがより大きなタプルの一部であるかどうかを確認します。
if set(short_tuple).issubset(longer_tuple):
# all elements of short_tuple are in longer_tuple
あなたは一度short_tuple
セットになりたい:
for short_tuple in mylist:
short_tuple_set = set(short_tuple)
for combo in itertools.combinations((range(1, 50)), 5):
if short_tuple_set.issubset(combo):
# matched!
ただし、一致することが保証されているすべての組み合わせを生成する方が効率的です。
for short_tuple in mylist:
short_tuple_set = set(short_tuple)
remainder = (i for i in range(1, 50) if i not in short_tuple_set)
for combo in itertools.combinations(remainder, 5 - len(short_tuple)):
combo = sorted(combo + short_tuple)
それぞれcombo
は、1 から 49 までの 5 つの数字の有効な組み合わせであり、short_tuple
その中に3 つの数字すべてが含まれています。考えられるすべての組み合わせを作成する必要はありません。
これらをジェネレーター関数として作成すると、同じ出力が生成されることを確認できます (タプルとリストは別としてsorted()
、リストを返します)。
>>> def set_test(mylist):
... for short_tuple in mylist:
... short_tuple_set = set(short_tuple)
... for combo in itertools.combinations((range(1, 50)), 5):
... if short_tuple_set.issubset(combo):
... yield combo
...
>>> def create_combos(mylist):
... for short_tuple in mylist:
... short_tuple_set = set(short_tuple)
... remainder = (i for i in range(1, 50) if i not in short_tuple_set)
... for combo in itertools.combinations(remainder, 5 - len(short_tuple)):
... combo = sorted(combo + short_tuple)
... yield combo
...
>>> all(a == tuple(b) for a, b in itertools.izip_longest(set_test(mylist), create_combos(mylist)))
True
しかし、2 番目の方法は非常に高速です。
>>> timeit('list(f(mylist))', 'from __main__ import set_test as f, mylist', number=10)
14.483195066452026
>>> timeit('list(f(mylist))', 'from __main__ import create_combos as f, mylist', number=10)
0.019912004470825195
はい、それはほぼ1000 倍高速です。