首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何根据列表中项的多个结果计算列表?

如何根据列表中项的多个结果计算列表?
EN

Stack Overflow用户
提问于 2022-03-23 00:59:49
回答 5查看 143关注 0票数 3

我有一个名单A=[a,b,c,d]。我需要根据B中每个项目之间的操作来计算一个新的列表A

代码语言:javascript
运行
复制
B= [a, b-(a), c-(a+(b-a)), d-(a+(b-a)+(c-(a+(b-a)))) ]

有什么毕达通的方法吗?列表A并不总是一个4项列表,因此该解决方案需要可用于任意长度的列表。提前谢谢。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2022-03-23 01:36:23

请注意,列表的表达式可以简化为:

代码语言:javascript
运行
复制
B = [a, b-a, c-b, d-c]

考虑到这一点,我们可以使用列表理解:

代码语言:javascript
运行
复制
[y - x for x, y in zip([0] + data, data)]

例如,

代码语言:javascript
运行
复制
data = [1, 2, 7, 6]
result = [y - x for x, y in zip([0] + data, data)]
print(result)

产出:

代码语言:javascript
运行
复制
[1, 1, 5, -1]
票数 1
EN

Stack Overflow用户

发布于 2022-03-23 02:00:16

所有的术语都抵消掉(c-(a+(b-a))c - b简化为d - cd-(a+(b-a)+(c-(a+(b-a))))简化为d - c),因此这里的真正算法是,每个项等于匹配项减去前一个项。这极大地简化了事情:

代码语言:javascript
运行
复制
B = [A[0]]  # Initial term has no prior to subtract from it
B += [x - y for x, y in zip(A[1:], A)]  # All other terms computed by subtracting term n - 1 from term n

如果您想要一行(忽略导入),您可以插入一个虚拟0来获得第一个元素的结果,而不需要显式地将其大小写:

代码语言:javascript
运行
复制
from itertools import chain  # At top of file

B = [x - y for x, y in zip(A, chain([0], A))]

如果您喜欢使用map和朋友进行微优化,则可以将后者替换为:

代码语言:javascript
运行
复制
from operator import sub  # At top of file

B = [*map(sub, A, chain([0], A))]

并将所有工作推送到C层(不执行每个元素的字节码)。

票数 1
EN

Stack Overflow用户

发布于 2022-03-23 21:26:25

有两种解决方案不认为“抵消”(因为对于floatCounter这样的标准类型来说,这已经是错误的了,如下所示)。

如果我正确理解模式,第一个B值应该是第一个A值,然后每个下一个B值都应该是下一个A值减去所有以前B值的总和。这样做的一个方法是:

代码语言:javascript
运行
复制
B = []
for a in A:
    if not B:
        b = sumB = a
    else:
        b = a - sumB
        sumB = sumB + b
    B.append(b)

使用itertools.accumulateoperator.sub的乐趣

代码语言:javascript
运行
复制
B = A[:1]
B += map(sub, A[1:], accumulate(B))

测试:

代码语言:javascript
运行
复制
                        A = [31, 41, 59, 26]
reference                   [31, 10, 18, -33]
subtract_neighbors  correct [31, 10, 18, -33]
loop                correct [31, 10, 18, -33]
fun                 correct [31, 10, 18, -33]

                        A = [1, 1, 1e-20, 1e-20]
reference                   [1, 0, -1.0, 1e-20]
subtract_neighbors  wrong   [1, 0, -1.0, 0.0]
loop                correct [1, 0, -1.0, 1e-20]
fun                 correct [1, 0, -1.0, 1e-20]

                        A = [Counter(), Counter({None: 1}), Counter(), Counter({None: 1})]
reference                   [Counter(), Counter({None: 1}), Counter(), Counter()]
subtract_neighbors  wrong   [Counter(), Counter({None: 1}), Counter(), Counter({None: 1})]
loop                correct [Counter(), Counter({None: 1}), Counter(), Counter()]
fun                 correct [Counter(), Counter({None: 1}), Counter(), Counter()]

执行上述检查的代码(在网上试试!):

代码语言:javascript
运行
复制
def reference(A):
    a, b, c, d = A
    return [a, b-(a), c-(a+(b-a)), d-(a+(b-a)+(c-(a+(b-a)))) ]

def subtract_neighbors(A):
    a, b, c, d = A
    return [a, b-a, c-b, d-c]

def loop(A):
    B = []
    for a in A:
        if not B:
            b = sumB = a
        else:
            b = a - sumB
            sumB = sumB + b
        B.append(b)
    return B

def fun(A):
    B = A[:1]
    B += map(sub, A[1:], accumulate(B))
    return B

from collections import Counter
from itertools import accumulate
from operator import sub

funcs = [
    reference,
    subtract_neighbors,
    loop,
    fun,
]

tests = [
    [31, 41, 59,26],
    [1, 1, 1e-20, 1e-20],
    [Counter(), Counter([None])] * 2,
]

for A in tests:
    print('                        A =', A)
    for func in funcs:
        result = func(A)
        if func is reference:
            expect = result
            correctness = '       '
        else:
            correctness = 'correct' if result == expect else 'wrong  '
        print(f'{func.__name__:19}', correctness, result)
    print()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71580659

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档