Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在更新的列表中循环_Python_List_Itertools - Fatal编程技术网

Python 在更新的列表中循环

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

我正在处理两个专栏。一个有几个单独的数字,另一个有总和。我想把清单1和清单2配对。在每次迭代中,我删除匹配的数字。不一定所有数字都匹配,但我希望得到尽可能多的数字。如何确保循环继续迭代,但在完成所有匹配后终止

理想情况下,在下面的示例中,我希望以以下内容结束:

[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])


这只得到一个匹配,但不是最佳匹配:

导入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)]