有没有办法找出数字组合(存储在列表中)是否在更长的数字组合中(存储在单独的列表中)?
E.g。
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)
的组合。
具体来说,我不想要将(1, 2, 3, 4, 7)
分成三个组合的进一步组合。
理想情况下,我想将此内容写入for
语句,以便将mylist
的每个元素与serieslist
的每个元素进行比较。
答案 0 :(得分:2)
使用sets来查看你的元组是否是较大元组的一部分:
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
但第二种方法是所以更快:
>>> 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次更快。
答案 1 :(得分:0)
如果您的所有序列只包含唯一的数字(没有重复):
a = (1,4,7)
b = (1,2,3,4,7)
a_in_b = all(x in b for x in a)