嵌套循环,用于成对添加序列中的数字

时间:2018-03-05 21:21:02

标签: python python-3.x

我有一个清单:

the_list = [1, 2, 3, 4, 5]

接下来,我想从列表中对数字对进行求和,在下一步中对下一对进行求和,依此类推,直到最后只得到一个数字。接下来的步骤如下:

 [3, 5, 7, 9]
 [8, 12, 16]
 [20, 28]
 [48]

我使用循环来添加对:

the_list = [1, 2, 3, 4, 5]

for i in range(len(the_list) - 1):
    a, b = the_list[i], the_list[i + 1]
    c = a + b
    print (c)

给出了什么:

3
5
7
9

但我不知道如何将其循环到下一步。因为,目前只想到添加到新列表的一个非常糟糕的想法,这将是一个完全错误的想法与一个大的起始列表。怎么办呢?

6 个答案:

答案 0 :(得分:4)

你可以zip列表反对自己偏移一个索引,然后对连续元素求和,直到列表折叠为一个slngle值

l = [1, 2, 3, 4, 5]
while len(l) > 1:
    l = [i+j for i,j in zip(l, l[1:])]
    print(l)

输出

[3, 5, 7, 9]
[8, 12, 16]
[20, 28]
[48]

答案 1 :(得分:3)

一次循环并一次添加2个元素:

the_list = [1, 2, 3, 4, 5]

while len(the_list) > 1:
    the_list = [the_list[i] + the_list[i+1] for i in range(len(the_list)-1)]
    print(the_list)

输出:

[3, 5, 7, 9]
[8, 12, 16]
[20, 28]
[48]

编辑我会推荐@ CoryKramer的答案,它的表现比这个好:

In [1]: def get_to_one(arr):
   ...:     while len(arr) > 1:
   ...:         arr = [arr[i] + arr[i+1] for i in range(len(arr)-1)]
   ...:     return arr
   ...:
   ...: def kramer_solution(l):
   ...:     while len(l) > 1:
   ...:         l = [i + j for i, j in zip(l, l[1:])]
   ...:     return l
   ...:

In [2]: %timeit get_to_one(range(100))
1.01 ms ± 2.16 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [3]: %timeit kramer_solution(range(100))
646 µs ± 1.34 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [4]: %timeit get_to_one(range(200))
3.81 ms ± 14.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [5]: %timeit kramer_solution(range(200))
2.45 ms ± 19.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

答案 2 :(得分:3)

map()的另一个变体:

>>> from operator import add
>>> the_list = [1, 2, 3, 4, 5]
>>> while len(the_list) > 1:
...     the_list = list(map(add, the_list, the_list[1:]))
...     print(the_list)
... 
[3, 5, 7, 9]
[8, 12, 16]
[20, 28]
[48]

答案 3 :(得分:2)

您也可以使用递归:

post_build:
    commands:
      - printf '[{"name":"your.task.definition.name","imageUri":"%s"}]' $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG > imagedefinitions.json

artifacts:
    files: imagedefinitions.json

输出:

the_list = [1, 2, 3, 4, 5]
def pairs(current):
   d = [current[i]+current[i+1] for i in range(len(current)-1)]
   yield d
   if len(d) > 1:
      yield from pairs(d)

print(list(pairs(the_list)))

答案 4 :(得分:1)

这是一个有效的解决方案:

while len(the_list) > 1:
    the_list = [the_list[i]+the_list[i+1] for i in range(len(the_list)-1)] 

我确信有更好的方法可以做到这一点。最终,你的循环只会一次查看列表,因为for i in range(len(the_list)-1)一旦i = len(the_list)-2终止(range提供的值比给定参数少一个)。

据我所知,垃圾收集器会在将变量名the_list重新分配给新列表后处理剩余列表 - 但是,如果您担心在{的每次迭代中生成新列表{1}}循环就是这样:

while

答案 5 :(得分:1)

另一种具有递归和高阶函数的奇特解决方案。

def foo(the_list):
  if len(the_list) == 1:
    return the_list
  number_pairs = list(zip(the_list[0::1], the_list[1::1]))
  return foo(list(map(lambda x: x[0] + x[1], number_pairs)))

the_list = [1, 2, 3, 4, 5]
print(foo(the_list))