我有一个清单:
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
但我不知道如何将其循环到下一步。因为,目前只想到添加到新列表的一个非常糟糕的想法,这将是一个完全错误的想法与一个大的起始列表。怎么办呢?
答案 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))