簡體   English   中英

使用字典理解壓縮/轉換嵌套列表

[英]Condenseing/converting a nested list using dictionary comprehension

所以我的數據結構化在一個嵌套列表中

data = [['A', '1'], ['B', '2'], ['C', '3'], ['A', '-2'], ['B', '4'], ['C', '1'], ['A', '2'], ['B', '1'], ['C', '-5']]

我正在嘗試將其轉換為如下所示的輸出

{'A': 1, 'C': -1, 'B': 7}

基本上總結所有的 A、B 和 C,將輸出作為字典。

我寫了這段代碼,給出了正確的答案

playerSum = {}
for ele in data:
    if ele[0] not in playerSum:
        playerSum[ele[0]] = int(ele[1])
    else:
        playerSum[ele[0]] += int(ele[1])

但是,我正在嘗試將上面的代碼塊轉換為字典理解。 我主要了解如何做到這一點,但我不明白如何將 += 寫成字典理解。 任何關於結構的指導都會很棒。

到目前為止我有這個

playerSum = {ele[0]: int(ele[1]) if ele[0] not in playerSum else playerSum[ele[0]] += int(ele[1]) for ele in data}

編輯:所以@achampion 能夠解決它。 謝謝!

{key: sum(int(v) for k, v in data if k==key) for key in set(k for k, _ in data)}

把它作為一種理解來做是不切實際的。
作為練習,您可以使用協程為您進行計數,但您可以有效地創建字典兩次:

from collections import defaultdict
def count():
    cache = defaultdict(int)
    k, v = yield
    while True:
        cache[k] += v
        k, v = yield cache[k]

counter = count()  # Create coroutine
next(counter)      # Prime coroutine

data = [['A', '1'], ['B', '2'], ['C', '3'], ['A', '-2'], ['B', '4'],
        ['C', '1'], ['A', '2'], ['B', '1'], ['C', '-5']]

{k: counter.send((k, int(v))) for k, v in data}  # Meets the challenge :)

結果:

{'A': 1, 'B': 7, 'C': -1}

或者一個真正丑陋的單行,不需要協程並且不是二次的(不是理解):

>>> reduce(lambda d, (k,v): d.__setitem__(k, d.get(k,0)+int(v)) or d, data, {})  # Py2.7
{'A': 1, 'B': 7, 'C': -1}

最后是一個基於@Prune 的非常低效但真正的 dict 理解:

>>> {key: sum(int(v) for k, v in data if k==key) for key in set(k for k, _ in data)}
{'A': 1, 'B': 7, 'C': -1}

最好的方法是最明顯的方法

from collections import defaultdict
playerSum = defaultdict(int)

for key, value in data:
   playerSum[key] += int(value)

這是不可能使用字典理解為你的價值觀會被覆蓋,該字典還沒有生成,直到理解完成即便如此,如果你能有什么好+ =。 就目前而言,除非您在某處有playerSum = {}否則您的代碼將出現 NameError 錯誤,如果您這樣做,您只是將名稱重新綁定到 dict comp 的結果,因此playerSum = {}基本上什么都不做。

做你想做的唯一方法是按照你自己的解決方案。 為了更有效的方法您可以解壓縮子列表並將第二個元素轉換為 int,使用collections.defaultdict對值求和:

from collections import defaultdict

d = defaultdict(int)

for a,b  in data:
    d[a] += int(b)

print(d)
defaultdict(<type 'int'>, {'A': 1, 'C': -1, 'B': 7})

或使用常規字典:

d = {}

for a, b in data:
    d[a] = d.get(a,0) + int(b)

print(d)
{'A': 1, 'C': -1, 'B': 7}

正如你所問的,我是在一個單一的理解中做到的。

dict ([(key, sum(int(elem[1]) for elem in data if elem[0]==key)) for key in [id for id in set([elem[0] for elem in data])] ])

從外到內:

  • 構建列表中使用的一組 ID。

  • 對於每個 ID,列出相關值。

  • 匯總列表。

  • 發出(產生)ID 並成對求和。

  • 將這個元組列表變成字典。

測試:

data = [['A', '1'], ['B', '2'], ['C', '3'],
        ['A', '-2'], ['B', '4'], ['C', '1'],
        ['A', '2'], ['B', '1'], ['C', '-5']]
playerSum = dict ([(key, sum(int(elem[1]) for elem in data if elem[0]==key))
                   for key in [id for id in set([elem[0] for elem in data])] ])
print data
print playerSum

結果:

[['A', '1'], ['B', '2'], ['C', '3'], ['A', '-2'], ['B', '4'], ['C', '1'], ['A', '2'], ['B', '1'], ['C', '-5']]
{'A': 1, 'C': -1, 'B': 7}

暫無
暫無

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

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