Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.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_Python 3.x - Fatal编程技术网

Python 成对地从序列中添加数字的嵌套循环

Python 成对地从序列中添加数字的嵌套循环,python,python-3.x,Python,Python 3.x,我有一份清单: 列表=[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

我有一份清单:

列表=[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

但我不知道如何循环到下一步。因为,就目前而言,只有一个非常糟糕的想法加入到新的列表中,这将是一个完全错误的想法,有一个大的起始列表。如何做到这一点?

只需循环并一次添加两个元素:

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

您可以
zip
将列表自身偏移一个索引,然后对连续元素求和,直到列表折叠为一个单值

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]

您还可以使用递归:

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)))
输出:

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

另一个带有
map()
的变体:


以下是一个有效的解决方案:

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
提供的值比给定参数小一个)

据我所知,垃圾收集器将在将变量名
重新分配给一个新列表后处理剩余列表——但是,如果您担心在
循环中每次迭代都会生成一个新列表,而
循环中有以下情况:

while len(the_list) > 1:
    for i in range(len(the_list)-1):
        a, b = the_list[i], the_list[i + 1]
        c = a + b
        the_list[i] = c
    the_list.pop()

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

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

你也不需要
[:]
,只要
l
就行了,因为我的答案比我的更干净,我建议你使用这个答案。有趣的解决方案:)非常干净!美好的