Python 在更新的列表中循环
我正在处理两个专栏。一个有几个单独的数字,另一个有总和。我想把清单1和清单2配对。在每次迭代中,我删除匹配的数字。不一定所有数字都匹配,但我希望得到尽可能多的数字。如何确保循环继续迭代,但在完成所有匹配后终止 理想情况下,在下面的示例中,我希望以以下内容结束: [5,6],11\n [2,3],5 当然,如果整个方法不正确,请随时提出建议 谢谢你的帮助Python 在更新的列表中循环,python,list,itertools,Python,List,Itertools,我正在处理两个专栏。一个有几个单独的数字,另一个有总和。我想把清单1和清单2配对。在每次迭代中,我删除匹配的数字。不一定所有数字都匹配,但我希望得到尽可能多的数字。如何确保循环继续迭代,但在完成所有匹配后终止 理想情况下,在下面的示例中,我希望以以下内容结束: [5,6],11\n [2,3],5 当然,如果整个方法不正确,请随时提出建议 谢谢你的帮助 import itertools list1=[5,6,2,3,8,7] list2=[11,5] combos=list(itertool
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])
这只得到一个匹配,但不是最佳匹配:
导入itertools
列表1=[5,6,2,3,8,7]
清单2=[11,5]
组合=列表(itertools.compositions(列表1,2))
结果=[]
对于范围内的i(len(组合)):
如果列表2中的sum(组合[i])和列表1中的(组合[i][0]和列表1中的组合[i][0]:
result.append(组合[i])
列表1.删除(组合[i][0])
列表1.删除(组合[i][1])
清单2.删除(和(组合[i]))
打印(结果)
#输出:[(5,6)、(2,3)]
对于以下输入,它只找到一些匹配,而不是大多数匹配(取决于组合检查的顺序):
list1=[5,6,2,8,3,7]
列表2=[11,5,10,15]
#输出:[(5,6)、(2,8)]
列表1=[5,6,2,3,8,7]
列表2=[11,5,10,15]
#输出:[(5,6)、(2,3)、(8,7)]
就您的问题而言,我认为:
- 有两个类似列表的存储,元素(INT)的顺序未排序李>
- 元素可能在两个存储中重复李>
- 从第一个序列开始的任何长度的每个组合都可以通过特殊功能(总和)被“加工”到第二个存储器中的对应元素李>
- 尽可能多地(或可能是所有)应在找到匹配项后立即
找到并检索该匹配项(通过产量或印刷)李>- 从两个存储中找到后,应立即删除与此类匹配对应的所有唯一元素李>
- 允许每个存储创建不超过一个
副本李>- 匹配算法应该是有限的
- 从第一个序列开始的任何长度的每个组合都可以通过特殊功能(总和)被“加工”到第二个存储器中的对应元素李>
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=[]
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}
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]
示例2:查找所有长度组合的所有和匹配。相关问题
结果:
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=[]
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}
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]
例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=(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=[]
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}
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]
它向我显示了以下错误
TypeError:'itertools.combines'对象不可下标
如果要处理组合列表,请使用combos=list(itertools.combines(list1,2))
谢谢大家。你说得对。在我匆忙地把问题弄清楚的过程中,我忘了复制一个单元格,在那里我把它变成了一个列表。我不清楚你想要什么。根据你的(示例)输入,你能给出一个预期结果吗?总和总是两个数字吗?如果不是,这个问题就是NP难问题。你基本上是在试图解决一系列相关的问题。它也可以被视为一种类型。15是从哪里来的?为什么要在列表1和列表2中添加数字?他们应该只在匹配后才从中删除号码。我刚刚将匹配添加到名为“结果”的新列表中,看起来您也在更新列表1和列表2,这与我们想要的不同。这是您的代码的正确版本,正如您提到的“我删除匹配的号码”,您正在删除和更新列表1、列表2。在你的问题中没有关于“不更新”的任何内容。如果你尝试执行你自己的代码,你会发现它不会产生你想要的结果。您的代码输出是(2,3)。正确的输出是[(5,6),(2,3)]