简体   繁体   English

如何确定数字组合是否在另一个数字组合中?

[英]How do I find out if a combination of numbers are in another combination of numbers?

Is there a way to find out if a combination of numbers (stored in a list) are in a longer combination of numbers (stored in a separate list)? 有没有办法找出数字组合(存储在列表中)是否在更长的数字组合中(存储在单独的列表中)?

Eg 例如

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

In the example above, I would want to return that the combination of numbers (1, 4, 7) is in the combination of numbers (1, 2, 3, 4, 7) . 在上面的例子中,我想要返回的是数字组合(1, 4, 7) 数字组合(1, 2, 3, 4, 7)

Specifically though, I don't want to split (1, 2, 3, 4, 7) into further combinations of three. 具体地,虽然,我不想拆分(1, 2, 3, 4, 7)为三个的其它组合。

Ideally, I'd like to write this into a for statement to compare each element of mylist to each element of serieslist . 理想情况下,我想将其写入for语句,以将mylist的每个元素与serieslist每个元素进行serieslist

Use sets to see if a your tuple is part of the larger tuple: 使用集来查看你的元组是否是更大元组的一部分:

if set(short_tuple).issubset(longer_tuple):
    # all elements of short_tuple are in longer_tuple

You want to turn short_tuple into a set once : 要打开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!

It'd be more efficient to generate all combinations that are guaranteed to be matches though: 尽管如此,生成所有保证匹配的组合会更有效:

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)

Each combo is a valid combination of 5 numbers between 1 and 49 inclusive that have all 3 numbers of the short_tuple in them, without having to create all possible combinations. 每个combo是1到49之间的5个数字的有效组合,其中包含short_tuple所有3个数字, 不必创建所有可能的组合。

If you create these as generator functions, you can verify that they produce the same output (apart from tuples versus lists; sorted() returns a list): 如果将它们创建为生成器函数,则可以验证它们是否生成相同的输出(除了元组与列表之外; 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

but the second method is so much faster: 但第二种方法是如此之快:

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

Yes, that is nearly 1000 times faster. 是的,这快了近1000倍

If all your sequences only contain unique numbers (no duplicates): 如果所有序列仅包含唯一编号(无重复):

a = (1,4,7)
b = (1,2,3,4,7)
a_in_b = all(x in b for x in a)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM