0

数字の組み合わせ (リストに格納されている) がより長い数字の組み合わせ (別のリストに格納されている) に含まれているかどうかを調べる方法はありますか?

例えば

mylist = [(1, 4, 7), (3, 6, 9)]

serieslist = list(itertools.combinations((range(1, 50)), 5))
>> [(1, 2, 3, 4, 5), (1, 2, 3, 4, 6), (1, 2, 3, 4, 7)...etc...]

(1, 4, 7) 上記の例では、数字の組み合わせが数字の組み合わせにあることを返したいと思います(1, 2, 3, 4, 7)

具体的には、さらに 3 つの組み合わせに分割したくありません。(1, 2, 3, 4, 7)

理想的には、これをステートメントに書き込んで、 の各要素を の各for要素と比較したいと思います。mylistserieslist

4

2 に答える 2

2

セットを使用して、タプルがより大きなタプルの一部であるかどうかを確認します。

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 倍高速です。

于 2013-06-07T22:26:23.400 に答える
0

すべてのシーケンスに一意の番号のみが含まれている (重複がない) 場合:

a = (1,4,7)
b = (1,2,3,4,7)
a_in_b = all(x in b for x in a)
于 2013-06-07T22:29:30.023 に答える