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...]

在上面的示例中,我想返回 numbers的组合是 numbers(1, 4, 7) 组合(1, 2, 3, 4, 7)

但具体来说,我不想分成(1, 2, 3, 4, 7)三个进一步的组合。

理想情况下,我想把它写成一个for语句来mylist比较serieslist.

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 个数字的有效组合,其中包含所有 3 个数字short_tuple无需创建所有可能的组合。

如果将它们创建为生成器函数,则可以验证它们是否产生相同的输出(除了元组与列表;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

但第二种方法快得多:

>>> 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 回答