请问如何计算 Python 列表连续正数或连续负数的和?

2021-08-19 12:06:05 +08:00
 going

请问如何高效计算 Python 列表连续正数或连续负数的和?

案例:[1,3,5,-2,-1,3,5,2,-1,-3,-3]

期望结果:[9,-3,10,-7]

3670 次点击
所在节点    Python
41 条回复
Gorgine
2021-08-19 15:55:55 +08:00
from itertools import groupby
your_list = [1, 3, 5, -2, -1, 3, 5, 2, -1, -3, -3]
print([sum(item[1]) for item in groupby(your_list, lambda item: item > 0)])
Gorgine
2021-08-19 16:02:06 +08:00
fkdtz
2021-08-19 16:14:56 +08:00
话题无关:楼上代码没有一个能正常格式化的,贴图也是,鲜有一次就能贴对的。好奇为啥回帖的 markdown 要搞得这么难以捉摸。
lostvincent
2021-08-19 16:21:50 +08:00
没写过 py,就写点伪代码了

list = [...]
result = []
total = list[0]

for (i = 1; i < len(list)); i++) {
// total 和 list[i] 同符号
if ((total > 0) === (list[i] > 0)) {
total += list[i]
} else {
append(result, total)
total = list[i]
}
}

append(result, total)
return result

========
思路就是 total 记录累加
total 和当前元素符号(正负号)不同了,就记录累加结果到 result,重置 total 然后开始下一轮
题目写的是连续正负数,如果有 0 的话,遇到直接 continue
kasusa
2021-08-19 16:29:51 +08:00
@fkdtz 好像是只有帖子本身支持 markdown,但是回复贴不支持。
zouzou0208
2021-08-19 16:46:23 +08:00
@lizytalk [sum(i[1]) for i in groupby(x, key=lambda _: _ > 0)]
hahastudio
2021-08-19 18:36:01 +08:00
可不可以有 0 ?有的话 0 怎么算?是继续还是单独算?
gist.github.com/hahastudio/ec6c851a67c714ac40cf406a2aeeb525
laduary
2021-08-19 22:10:45 +08:00
用 arr[idx] * arr[idx -1] 判断正负
https://paste.ubuntu.com/p/gpFNhcPwYm/
mxT52CRuqR6o5
2021-08-19 22:25:04 +08:00
随便写写都是 o(n),都差不多的
0ZXYDDu796nVCFxq
2021-08-19 22:37:00 +08:00
@hahastudio 0 其实不影响结果
zxCoder
2021-08-19 22:45:42 +08:00
怎么个高效法。。。。
yinheli
2021-08-19 23:26:29 +08:00
@lizytalk 直接把 group 结果做 sum 不就可以?

```python

from itertools import groupby
[sum(g) for _, g in groupby([1,3,5,-2,-1,3,5,2,-1,-3,-3], key=lambda x: x > 0)]

```
ipwx
2021-08-20 00:19:52 +08:00
在 C++ 里面我就 i=0; j=0 开始原地求和,最后设一下 size,最高效。
lixiang2017
2021-08-20 01:08:23 +08:00
说一下题外话。建议多刷题,这种在力扣属于 easy
msg7086
2021-08-20 05:39:21 +08:00
@fkdtz 回帖啥时候有 markdown 的。
2i2Re2PLMaDnghL
2021-08-20 11:44:13 +08:00
@lizytalk 这并不 pythonic,这是 functional
不过 list(map(...)) 都可以轻易地改成 comprehension list
yucongo
2021-08-20 12:52:43 +08:00
from functools import reduce

lst = [1,3,5,-2,-1,3,5,2,-1,-3,-3]
reduce(lambda x, y: x[:-1] + [x[-1] + lst[y]] if lst[y] * lst[y-1] > 0 else x +[lst[y]], range(1, len(lst[1:]) + 1), [lst[0]])
# [9, -3, 10, -7]
dallaslu
2021-08-20 19:01:20 +08:00
@msg7086 肉眼 markdown
rudy1224
2021-08-21 18:05:41 +08:00
把目前回帖里面的方法对比了一下,加上了使用 NumPy+Numba 的数据:


代码在此:
<script src="https://gist.github.com/luhuidi/77ec31edfece0412d0058601e0f1a1ce.js"></script>
imn1
2021-08-26 14:50:48 +08:00
代码我就懒得写了,楼上很多 for 都能搞定,我给另一个解法:
itertools.groupby,把连续+/-的分组,然后每组 sum 就是了,代码少很多,应该两三行就够了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/796730

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX