簡體   English   中英

根據另一個列表中的索引匯總一個列表中的元素

[英]Summing up elements from one list based on indices in another list

所以這就是我試圖在 Python 中實現的目標:

  • 我有一個帶有未排序和重復索引的列表“A”。
  • 我有一個帶有一些浮點值的列表“B”
  • 長度 A = 長度 B
  • 我想以升序排序的方式根據 A 中的重復索引列出帶有 B 總和值的“C”。

例子:

A = [0, 1, 0, 3, 2, 1, 2]  # (indicates unsorted and repeated indices)
B = [25, 10, 15, 10, 5, 30, 50]  # (values to be summed)
C = [25+15, 10+30, 5+50, 15]  # (summed values in a sorted manner)

到目前為止,我知道如何使用以下方法進行排序:

C = zip(*sorted(zip(A, B)))

得到結果:

[(0, 0, 1, 1, 2, 2, 3), (15, 25, 10, 30, 5, 50, 10)] 

但我不知道如何做總和。

創建列表 C 的好方法是什么?

zip()dict結合使用:

A = [0 , 1 , 0 , 3 , 2 , 1 , 2] 
B = [25 , 10 , 15 , 10 , 5 , 30 , 50]

sums = {}
for key, value in zip(A,B):
    try:
        sums[key] += value
    except KeyError:
        sums[key] = value
print(sums)
# {0: 40, 1: 40, 2: 55, 3: 10}

在 ideone.com 上查看演示

如果訂單很重要,您可以使用groupby

In [1]: A=[0 , 1 , 0 , 3 , 2 , 1 , 2]

In [2]: B=[25 , 10 , 15 , 10 , 5 , 30 , 50]

In [3]: from itertools import groupby

In [4]: from operator import itemgetter

In [5]: C = [sum(map(itemgetter(1), group))
   ...:      for key, group in groupby(sorted(zip(A, B)),
   ...:                                key=itemgetter(0))]

In [6]: C
Out[6]: [40, 40, 55, 10]

defaultdict(float) ,如果沒有:

In [10]: from collections import defaultdict

In [11]: res = defaultdict(float)

In [12]: for k, v in zip(A, B):
    ...:     res[k] += v
    ...:     

In [13]: res
Out[13]: defaultdict(float, {0: 40.0, 1: 40.0, 2: 55.0, 3: 10.0})

請注意,python 中的dict是無序的(您不要相信任何 CPython 實現細節)。

實際上有點不清楚你想要什么,但是如果你希望它們被任何數字索引,你甚至不應該使用列表,而是使用計數器:

>>> from collections import Counter
>>> c = Counter()
>>> A = [0, 1, 0, 3, 2, 1, 2]
>>> B = [25, 10, 15, 10 , 5, 30, 50]
>>> for k, v in zip(A, B):
...     c[k] += v
...
>>> c
Counter({2: 55, 0: 40, 1: 40, 3: 10})
>>> c[0]
40

如果你真的想要一個列表,你可以使用

>>> [i[1] for i in sorted(c.items())]

但是任何丟失的鍵都會導致其余的值顯示在上面,這可能是也可能不是你想要的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM