如何迭代并将列表中的每个元素与另一个元素相加以找到一个数字?

时间:2015-07-20 08:10:31

标签: python algorithm python-2.7 data-structures itertools

我正在接受编程挑战并且遇到了这个问题,我不知所措地陷入了困境。 我得到了一份清单: [10, 13, 15, 18, 20, 15] 我必须找到这个中的任何元素的总和是否会提供结果30并且输出应该是计数 我们可以看到有两种可能性,10 + 20 = 30和15 + 15,所以计数为2。 但是如何使用for循环或itertools或任何切片或功能解决方案?

4 个答案:

答案 0 :(得分:5)

您可以在itetools.combinations中使用sum和生成器表达式:

>>> my_list=[10, 13, 15, 18, 20, 15]
>>> from itertools import combinations
>>> sum(i+j==30 for i,j in combinations(my_list,2))
2

如果您也想要这些项目,您可以使用列表理解:

>>> [(i,j) for i,j in combinations(my_list,2) if i+j==30]
[(10, 20), (15, 15)]

答案 1 :(得分:4)

>>> from itertools import combinations
>>> lst = [10, 13, 15, 18, 20, 15]
>>> count = 0
>>> for x, y in combinations(lst, 2):
        if x + y == 30:
            print(x, y)
            count += 1

10 20
15 15

>>> print(count)
2

答案 2 :(得分:3)

或者如果您不想使用itertools,您可以使用以下列表理解来完成

 len([(ii,jj) for i, ii in enumerate(a) for j, jj in enumerate(a[i+1:]) if ii+jj==30])

给你

 len([(10, 20), (15, 15)]) = 2

组合方法大约一半时间运行。

答案 3 :(得分:0)

由于这来自编程挑战,这里的解决方案在列表长度上具有线性复杂性(使用组合将获得二次复杂度):

from collections import defaultdict
def count_pairs_summing_to(lst, n):  
    element_counter = defaultdict(int)
    count = 0
    for x in lst:
        if (n - x) in element_counter:
            count += element_counter[n - x]
        element_counter[x] += 1
    return count

我们的想法是对数据进行一次传递,并跟踪我们之前在哈希表中看到的元素。 当我们看到新元素x时,我们只需要知道我们之前是否看过30 - x 我们还会跟踪我们看到每个元素的次数,以确保我们计算重复对(例如count_pairs_summing_to([10, 10, 20, 25], 30)应该返回2。)。

一些基准测试:

lst = [10, 13, 15, 18, 20, 15]

%timeit sum(i+j==30 for i,j in combinations(lst,2))
100000 loops, best of 3: 3.35 µs per loop

%timeit len([(ii,jj) for i, ii in enumerate(lst) for j, jj in enumerate(lst[i+1:]) if ii+jj==30])
100000 loops, best of 3: 6.59 µs per loop

%timeit count_pairs_summing_to(lst, 30)
100000 loops, best of 3: 2.92 µs per loop

# With a slightly bigger list.
import numpy.random as random
big_lst = list(random.randint(0, 100, size=1000))

%timeit len([(ii,jj) for i, ii in enumerate(big_lst) for j, jj in enumerate(big_lst[i+1:]) if ii+jj==30])
10 loops, best of 3: 125 ms per loop

%timeit sum(i+j==30 for i,j in combinations(big_lst,2))
1 loops, best of 3: 1.21 s per loop

# The previous one was surprisingly slow but it can be fixed:
%timeit sum(1 for i,j in combinations(big_lst,2) if i+j==30)
1 loops, best of 3: 88.2 ms per loop

%timeit count_pairs_summing_to(big_lst, 30)
1000 loops, best of 3: 504 µs per loop