推荐学习书目
› Learn Python the Hard Way
Python Sites
› PyPI - Python Package Index
› http://diveintopython.org/toc/index.html
› Pocoo
值得关注的项目
› PyPy
› Celery
› Jinja2
› Read the Docs
› gevent
› pyenv
› virtualenv
› Stackless Python
› Beautiful Soup
› 结巴中文分词
› Green Unicorn
› Sentry
› Shovel
› Pyflakes
› pytest
Python 编程
› pep8 Checker
Styles
› PEP 8
› Google Python Style Guide
› Code Style from The Hitchhiker's Guide
going
V2EX  ›  Python

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

  •  
  •   going · Aug 19, 2021 · 4890 views
    This topic created in 1906 days ago, the information mentioned may be changed or developed.

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

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

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

    41 replies  •  2021-08-26 14:52:06 +08:00
    unixeno
    unixeno
    Aug 19, 2021 via Android
    1
    这个不是循环一遍就出来了吗
    zzzain46
    zzzain46
    Aug 19, 2021 via iPhone
    2
    请学习 for 循环
    nobody1234
    nobody1234
    Aug 19, 2021 via iPhone
    3
    维护好两个下标,遍历一次搞定
    lizytalk
    lizytalk
    Aug 19, 2021❤️6
    4
    要说 pythonic 的话可以这样
    x = [1,3,5,-2,-1,3,5,2,-1,-3,-3]
    list(map(lambda item: sum(item[1]), groupby(x, key=lambda _: _ > 0)))
    lizytalk
    lizytalk
    Aug 19, 2021❤️1
    5
    如果不需要 pythonic 的话还是 for 循环吧,遍历一遍就可以
    ch2
    ch2
    Aug 19, 2021
    6
    nums=[1,3,5,-2,-1,3,5,2,-1,-3,-3]
    upper=[]
    lower=[]
    result=[]
    for num in nums:
    if num>0:
    if len(upper)==0:
    if len(lower)>0:
    result.append(sum(lower))
    lower=[]
    upper.append(num)
    else:
    if len(lower)==0:
    if len(upper)>0:
    result.append(sum(upper))
    upper=[]
    lower.append(num)
    if len(upper) > 0:
    result.append(sum(upper))
    if len(lower) > 0:
    result.append(sum(lower))
    print(result)
    kasusa
    kasusa
    Aug 19, 2021
    7
    ```
    list1 = [1,3,5,-2,-1,3,5,2,-1,-3,-3] #原数据
    list2 = [] #结果输出
    a = list1[0] #计算从 2 开始

    for index in range(1,len(list1)):
    if list1[index] * list1[index - 1] < 0: #有换号,将结果添加到 list2,、把 a 归零
    list2.append(a)
    a = 0
    a += list1[index]
    else: #无换号,正常累加
    a += list1[index]
    list2.append(a) #将最后一个累加结果加入结果集

    print(list2)
    ```

    用到了数学中零点判定的知识。
    kasusa
    kasusa
    Aug 19, 2021
    8
    ```
    V2EX 不支持这个 markdown 语法吗?

    ```
    kasusa
    kasusa
    Aug 19, 2021
    9
    ```html
    是不是我的 markdown 语法有问题 >.>
    ```
    Kilerd
    Kilerd
    Aug 19, 2021
    10
    作业请独立完成
    xe2vherd
    xe2vherd
    Aug 19, 2021
    12
    @lizytalk 你这个不是连续的吧
    msg7086
    msg7086
    Aug 19, 2021
    13
    只懂 Ruby,写起来不难。
    x = [1, 3, 5, -2, -1, 3, 5, 2, -1, -3, -3]
    x.chunk(&:positive?).map(&:last).map(&:sum) #=> [9, -3, 10, -7]

    Python 里如果有类似的方法的话照着改一下就行了吧。
    huntagain2008
    huntagain2008
    Aug 19, 2021
    14
    非程序员,看着文档学了 for 循环,不知道写的对不对。
    ``` python
    a=[1,3,5,-2,-1,3,5,2,-1,-3,-3]
    b=[]
    for i in range(len(a)):
    if i<len(a)-1:
    if a[i]*a[i+1]>0:
    a[i+1]=a[i]+a[i+1] # 比如 1+3 取 4 的结果放在下标 a[1]
    else:
    b+=[a[i]] # 遇到正负不同的,比如遇到-2 取 a[2]作为和
    kasusa
    kasusa
    Aug 19, 2021
    15
    感觉小题目还挺益智的。
    不过 V2EX 显示代码真是难受。没有高亮、没有缩进。
    huntagain2008
    huntagain2008
    Aug 19, 2021
    16
    @huntagain2008
    ``` python

    a=[1,3,5,-2,-1,3,5,2,-1,-3,-3]
    b=[]
    for i in range(len(a)):
    if i<len(a)-1:
    if a[i]*a[i+1]>0:
    a[i+1]=a[i]+a[i+1] # 比如 1+3 取 4 的结果放在下标 a[1]
    else:
    b+=[a[i]] # 遇到正负不同的,比如遇到-2 取 a[2]作为和

    ```
    huntagain2008
    huntagain2008
    Aug 19, 2021
    17
    @huntagain2008 好吧,错了。
    a=[-2,1,3,5,-2,-1,3,5,2,-1,-3,-3]经过这段代码变成了[-2, 1, 4, 9, -2, -3, 3, 8, 10, -1, -4, -7]
    b 的值只有[-2, 9, -3, 10],后面的-12 没有求和了。
    learningman
    learningman
    Aug 19, 2021
    18
    @kasusa #8 V2EX 只支持在主题中用 markdown,回复要贴代码要用 GitHub Gist
    huntagain2008
    huntagain2008
    Aug 19, 2021
    19
    @huntagain2008 改了下,还是不知道这次对不对。
    >>>a=[-2, 1, 4, 9, -2, -3, 3, 8, 10, -1, -4, -7]
    >>> b=[]
    >>> for i in range(len(a)):
    ... if i<len(a)-1:
    ... if a[i]*a[i+1]>0:
    ... a[i+1]=a[i]+a[i+1] # 比如 1+3 取 4 的结果放在下标 a[1]
    ... else:
    ... b+=[a[i]] # 遇到正负不同的,比如遇到-2 取 a[2]作为和
    ... else:
    ... b+=[a[i]] # 最后一次求和
    ...
    >>> b
    [-2, 14, -5, 21, -12]
    huntagain2008
    huntagain2008
    Aug 19, 2021
    20
    @huntagain2008 改了下,还是不知道这次对不对。
    >>>a=[-2, 1, 4, 9, -2, -3, 3, 8, 10, -1, -4, -7]
    >>> b=[]
    >>> for i in range(len(a)):
    ... if i<len(a)-1:
    ... ... if a[i]*a[i+1]>0:
    ... ... ... a[i+1]=a[i]+a[i+1] # 比如 1+3 取 4 的结果放在下标 a[1]
    ... ... else:
    ...... ... b+=[a[i]] # 遇到正负不同的,比如遇到-2 取 a[2]作为和
    ... else:
    ... ... b+=[a[i]] # 最后一次求和
    ...
    >>> b
    [-2, 14, -5, 21, -12]
    Gorgine
    Gorgine
    Aug 19, 2021
    21
    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)])
    fkdtz
    fkdtz
    Aug 19, 2021❤️1
    23
    话题无关:楼上代码没有一个能正常格式化的,贴图也是,鲜有一次就能贴对的。好奇为啥回帖的 markdown 要搞得这么难以捉摸。
    lostvincent
    lostvincent
    Aug 19, 2021
    24
    没写过 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
    kasusa
    Aug 19, 2021
    25
    @fkdtz 好像是只有帖子本身支持 markdown,但是回复贴不支持。
    zouzou0208
    zouzou0208
    Aug 19, 2021
    26
    @lizytalk [sum(i[1]) for i in groupby(x, key=lambda _: _ > 0)]
    hahastudio
    hahastudio
    Aug 19, 2021
    27
    可不可以有 0 ?有的话 0 怎么算?是继续还是单独算?
    gist.github.com/hahastudio/ec6c851a67c714ac40cf406a2aeeb525
    laduary
    laduary
    Aug 19, 2021
    28
    用 arr[idx] * arr[idx -1] 判断正负
    https://paste.ubuntu.com/p/gpFNhcPwYm/
    mxT52CRuqR6o5
    mxT52CRuqR6o5
    Aug 19, 2021 via Android
    29
    随便写写都是 o(n),都差不多的
    0ZXYDDu796nVCFxq
    0ZXYDDu796nVCFxq
    Aug 19, 2021 via Android
    30
    @hahastudio 0 其实不影响结果
    zxCoder
    zxCoder
    Aug 19, 2021
    31
    怎么个高效法。。。。
    yinheli
    yinheli
    Aug 19, 2021
    32
    @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
    ipwx
    Aug 20, 2021
    33
    在 C++ 里面我就 i=0; j=0 开始原地求和,最后设一下 size,最高效。
    lixiang2017
    lixiang2017
    Aug 20, 2021 via Android
    34
    说一下题外话。建议多刷题,这种在力扣属于 easy
    msg7086
    msg7086
    Aug 20, 2021
    35
    @fkdtz 回帖啥时候有 markdown 的。
    2i2Re2PLMaDnghL
    2i2Re2PLMaDnghL
    Aug 20, 2021
    36
    @lizytalk 这并不 pythonic,这是 functional
    不过 list(map(...)) 都可以轻易地改成 comprehension list
    yucongo
    yucongo
    Aug 20, 2021
    37
    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
    dallaslu
    Aug 20, 2021
    38
    @msg7086 肉眼 markdown
    rudy1224
    rudy1224
    Aug 21, 2021❤️1
    39
    把目前回帖里面的方法对比了一下,加上了使用 NumPy+Numba 的数据:


    代码在此:
    <script src="https://gist.github.com/luhuidi/77ec31edfece0412d0058601e0f1a1ce.js"></script>
    imn1
    imn1
    Aug 26, 2021
    40
    代码我就懒得写了,楼上很多 for 都能搞定,我给另一个解法:
    itertools.groupby,把连续+/-的分组,然后每组 sum 就是了,代码少很多,应该两三行就够了
    imn1
    imn1
    Aug 26, 2021
    41
    呃,原来有人说了,漏看了,pass
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   768 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 130ms · UTC 23:09 · PVG 07:09 · LAX 15:09 · JFK 18:09
    ♥ Do have faith in what you're doing.