我正在处理两列。一个有几个单独的数字,另一个有和。我想匹配list1和list2。在每次迭代中,我都会删除匹配的数字。不一定所有数字都匹配,但我想获得尽可能多的数字。我该如何确保循环继续迭代,但在完成所有匹配后终止?
理想情况下,在下面的示例中,我希望得到这样的结果:
[5,6],11 \ n [2,3],5
当然,如果整个方法不正确,请随时提出建议。
谢谢您的帮助。
import itertools
list1=[5,6,2,3,8,7]
list2=[11,5]
combos=list(itertools.combinations(list1, 2))
for i in range(len(list1)):
if sum(combos[i]) in list2:
list1.remove(combos[i][0])
list1.remove(combos[i][1])
list2.remove(sum(combos[i]))
combos=list(itertools.combinations(list1, 2))
print(combos[i])
答案 0 :(得分:0)
这只会带来一场比赛,但这并不是最好的一场比赛:
import itertools
list1=[5,6,2,3,8,7]
list2=[11,5]
combos=list(itertools.combinations(list1, 2))
result=[]
for i in range(len(combos)):
if sum(combos[i]) in list2 and (combos[i][0] in list1 and combos[i][0] in list1 ):
result.append(combos[i])
list1.remove(combos[i][0])
list1.remove(combos[i][1])
list2.remove(sum(combos[i]))
print(result)
#Output: [(5, 6), (2, 3)]
对于下面的输入,它只会找到一些匹配项,而不是最多的匹配项(取决于组合检查的顺序):
list1=[5,6,2,8,3,7]
list2=[11,5,10,15]
# Output: [(5, 6), (2, 8)]
list1=[5,6,2,3,8,7]
list2=[11,5,10,15]
# Output: [(5, 6), (2, 3), (8, 7)]
答案 1 :(得分:0)
只要您的问题不够明确,我认为:
提议的解决方案基于这些假设,并且几乎可以满足所有这些假设。但是,如果要具体化条件,则可以显着简化-确切的存储类型是什么?如果数据类型可以是collections.deque
或set
,那就太好了-从列表对象中删除元素是很昂贵的事情。另外,如果您的数据应该更新-应该何时更新(在搜索匹配项时-或之后)?数据中是否有重复的元素?是否可以创建输入存储的副本?如果可以,这种副本的最大数量是多少?搜索匹配项时是否可以对存储进行其他任何更改?在存储空间变空后算法应该停止吗?
from itertools import combinations, chain
def update_data_matches(data, matches, comb_lengths, get_match, discard_all, discard_all_from):
# itertools.combinations operates with tuple-copy of any input data,
# which type is not tuple. We need to create one copy explicitly
# to minimize number of created copies:
data_copy = tuple(data)
if isinstance(comb_lengths, int):
combs = combinations(data_copy, comb_lengths)
else:
combs = chain.from_iterable(combinations(data_copy, cl) for cl in comb_lengths)
matches_copy = frozenset(matches)
for comb in combs:
if (possible_match := get_match(comb)) in matches_copy:
discard_all(matches, possible_match)
discard_all_from(data, comb)
yield comb
def lst_discard_all(lst, element, i=0):
try:
while True:
del lst[(i := lst.index(element, i))]
except ValueError:
return
def lst_discard_all_from(lst, elements):
for i in range(len(lst)-1, -1, -1):
if lst[i] in elements:
del lst[i]
def lstset_discard_all(lst, element):
try:
lst.remove(element)
except ValueError:
return
def lstset_discard_all_from(lst, elements):
for e in elements:
try:
lst.remove(e)
except ValueError:
continue
def update_lst_data_matches(*args, **kwargs):
return update_data_matches(*args, discard_all=lst_discard_all,
discard_all_from=lst_discard_all_from, **kwargs)
def update_set_data_matches(*args, **kwargs):
return update_data_matches(*args, discard_all=set.discard,
discard_all_from=set.difference_update, **kwargs)
def update_lstset_data_matches(*args, **kwargs):
return update_data_matches(*args, discard_all=lstset_discard_all,
discard_all_from=lstset_discard_all_from, **kwargs)
在您的情况下:
data1 = [5,6,2,3,8,7]
data2 = [11,5]
for match in update_lstset_data_matches(data1, data2, 2, sum):
print(f'{match=}', f'{sum(match)=}', f'{data1=}', f'{data2=}')
结果:
match=(5, 6) sum(match)=11 data1=[2, 3, 8, 7] data2=[5]
match=(2, 3) sum(match)=5 data1=[8, 7] data2=[]
match=(3, 8) sum(match)=11 data1=[7] data2=[]
示例2:找到具有所有长度组合的所有总和匹配项。相关问题https://en.wikipedia.org/wiki/Subset_sum_problem
data3 = {-7, -3, 66, -2, 5, 8}
data4 = {0, 13, -9, 4, 19}
for match in update_set_data_matches(data3, data4, range(1, len(data3)), sum):
print(f'{match=}', f'{sum(match)=}', f'{data3=}', f'{data4=}')
结果:
match=(5, 8) sum(match)=13 data3={66, -7, -3, -2} data4={0, 4, 19, -9}
match=(-7, -2) sum(match)=-9 data3={66, -3} data4={0, 4, 19}
match=(5, -3, -2) sum(match)=0 data3={66} data4={4, 19}
match=(5, 8, -7, -2) sum(match)=4 data3={66} data4={19}
示例3:
data5 = [11, 123, 3, 66, -2, 11, 8, 66, 3.0, 3]
data6 = [0, 13, -9, 4.0, 123, 4, 19, 0]
for match in update_lst_data_matches(data5, data6, range(1, len(data5)), sum):
print(f'{match=}', f'{sum(match)=}', f'{data5=}', f'{data6=}')
结果:
match=(123,) sum(match)=123 data5=[11, 3, 66, -2, 11, 8, 66, 3.0, 3] data6=[0, 13, -9, 4.0, 4, 19, 0]
match=(11, 8) sum(match)=19 data5=[3, 66, -2, 66, 3.0, 3] data6=[0, 13, -9, 4.0, 4, 0]
match=(11, 8) sum(match)=19 data5=[3, 66, -2, 66, 3.0, 3] data6=[0, 13, -9, 4.0, 4, 0]
match=(3, -2, 3.0) sum(match)=4.0 data5=[66, 66] data6=[0, 13, -9, 0]
match=(3, -2, 3) sum(match)=4 data5=[66, 66] data6=[0, 13, -9, 0]
match=(-2, 3.0, 3) sum(match)=4.0 data5=[66, 66] data6=[0, 13, -9, 0]