遍历列表中的多个变量而无需重复计算?

时间:2018-08-30 15:56:57

标签: python python-3.x

我正在研究程序的一部分,其中我试图输入数字列表并返回3个数字的所有组,这些组的总和为0,而没有对每个数字进行两次或三次计数。这是我要去的地方:

def threeSumZero2(array):
    sums = []
    apnd=[sorted([x,y,z]) for x in array for y in array for z in array if x+y+z==0]
    for sets in apnd:
        if sets not in sums:
            sums.append(sets)
    return sums

我可以在第三行中添加任何代码以确保不返回[0,0,0]作为答案。

这是我的测试清单:

[-1,0,1,2,-1,4] 

谢谢

*编辑:对于重复的输入值,我应该进行澄清:此测试列表的预期结果是:

[[-1,-1,2],[-1,0,1]]

2 个答案:

答案 0 :(得分:3)

您想要组合而不替换,这是itertools提供的。然后可以将您的sums设为一组,以删除有关订购的重复项。

from itertools import combinations

def threeSumZero2(array):
    sums = set()
    for comb in combinations(array, 3):
        if sum(comb) == 0:
            sums.add(tuple(sorted(comb)))
    return sums

print(threeSumZero2([-1,0,1,2,-1,4]))

输出

{(-1, -1, 2), (-1, 0, 1)}

此解决方案也可以使用集合理解来更简洁地编写。

def threeSumZero2(nums):
    return {tuple(sorted(comb)) for comb in combinations(nums, 3) if sum(comb) == 0}

更高效的算法

尽管,上述算法需要遍历三项的所有组合,这使其成为 O(n 3

用于这种 n-sum 问题的一般策略是遍历 n-1 组合并对它们的和进行哈希处理,从而可以针对数字有效地对其进行测试在列表中。

算法复杂度下降了一个数量级,使其为 O(n 2

from itertools import combinations

def threeSumZero2(nums, r=3):
    two_sums = {}
    for (i_x, x), (i_y, y) in combinations(enumerate(nums), r - 1):
        two_sums.setdefault(x + y, []).append((i_x, i_y))

    sums = set()
    for i, n in enumerate(nums):
        if -n in two_sums:
            sums |= {tuple(sorted([nums[idx[0]], nums[idx[1]], n]))
                     for idx in two_sums[-n] if i not in idx}

    return sums

print(threeSumZero2([-1,0,1,2,-1,4]))

输出

{(-1, -1, 2), (-1, 0, 1)}

答案 1 :(得分:0)

您可以使用itertools进行此操作(请参见Oliver的答案),但是您也可以通过三个嵌套的for循环来获得结果:

def threeSumZero2(lst):
    groups = []
    for i in range(len(lst)-2):
        for j in range(i + 1, len(lst)-1):
            for k in range(j + 1, len(lst)):
                if lst[i] + lst[j] + lst[k] == 0:
                    groups.append((lst[i], lst[j], lst[k]))
    return groups

和您的测试:

>>> threeSumZero2([-1, 0, 1, 2, -1, 4])
[(-1, 0, 1), (-1, 2, -1), (0, 1, -1)]

哦,还有list!= array