1

首先第一個值我有一本字典D1看起來像這樣:從字典值列表中刪除的元組,如果在元組= 1

d1 = { 'w' : ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'c', 'c'], 
      'x' : ['d', 'd', 'd', 'e', 'e'], 
      'y' : ['f', 'f', 'g'], 
      'z' : ['h', 'i']  
    } 

然後我遍歷該字典,並作出新的字典,其中每個值一個包含兩個元素的列表:一個整數和一個列表。整數是d1中該值的字符串數。該列表包含元組,(在元組的0位置)包含字符串從d1(在元組的位置1)和的次數該字符串出現在D1的每個元組:

d2 = { 'w' : [10, [(5, 'a'), (3, 'b'), (2, 'c')], 
     'x' : [5, [(3, 'd'), (2, 'e')], 
     'y' : [3, [(2, 'f'), (1, 'g')], 
     'z' : [2, [(1, 'h'), (1, 'i')]  
    } 

我想刪除只所以最後我想出現一次(「G」,「H」,和「我」),任何字符串:

dFinal = { 'w' : [10, [(5, 'a'), (3, 'b'), (2, 'c')], 
       'x' : [5, [(3, 'd'), (2, 'e')], 
       'y' : [2, [(2, 'f')]  
     } 

我讀的是什麼,我相信一個例子是字典解析去除整部字典如果值列表的長度小於2:

d = {k:v for k,v in d.items() if len(v) > 1} 

我試圖掌握列表/字典解析,並希望使用這樣的事情來實現我所描述的內容,並沿途學習。

起初我試圖編寫一個函數,它將d2作爲參數,但我不知道如何引用每個元組的位置0。

然後認爲使用沒有元組的d1來製作dFinal可能會容易得多,而不是試圖改變d2。

如果你能描述一個乾淨的方式從D1 和/或 D2使dFinal,並解釋的思維過程,我真的很感激它。兩者都能真正幫助我理解如何用理解精確地操作字典列表。

謝謝!

回答

3

那麼,您可以使用Counter對象。老實說,我會使用循環,因爲它可能會更有效率。

In [1]: from collections import Counter 

編輯:這是我如何會真正做到這一點,沒有內涵:

In [17]: for k,v in d1.items(): 
    ...:  counts = Counter(v) 
    ...:  counts = [t for t in counts.items() if t[1] > 1] 
    ...:  if len(counts) > 0: 
    ...:   dfinal[k] = [sum(c[1] for c in counts), counts] 
    ...: 

In [18]: dfinal 
Out[18]: 
{'w': [10, [('b', 3), ('a', 5), ('c', 2)]], 
'x': [5, [('d', 3), ('e', 2)]], 
'y': [2, [('f', 2)]]} 
+0

非常感謝。然而,這不會在每個值的開始處調整「總和整數」。 10,5和3需要變成10,5和2. – ddrsee

+0

@ddrsee錯過了那個。輕鬆修復。 –

+0

非常感謝。我會閱讀有關計數器,並試圖找出這裏發生了什麼... – ddrsee

1

我不認爲這是良好的作風,但你可以做這樣的:

dFinal = {k: [sum([i for i, c in v[1] if i != 1]), 
       [(i, c) for i, c in v[1] if i != 1]] 
      for k, v in d2.items() 
      if [(i, c) for i, c in v[1] if i != 1]} 

編輯:現在更新計數。再一次,如果理解看起來像這樣,是時候重構了。

+0

這不會調整成員數「y」:[3,[(2,'f')]]'儘管現實,他們可能不是必要的。 – TemporalWolf

+0

他們是必要的! :-) – ddrsee

+0

非常感謝。你有這樣的理解(以及什麼是重構)最喜歡的教程? – ddrsee

1

from collections import Counter 

d2 = {k: [len(v), sorted(Counter(v).items())] for k, v in d1.items()} 

dFinal = {k: [v1, [(y, x) for x, y in v2 if y > 1]] for k, (v1, v2) in d2.items()} 

d2dFinal略有不同,從你的。這是我的d2

{'w': [10, [('a', 5), ('b', 3), ('c', 2)]], 
'x': [5, [('d', 3), ('e', 2)]], 
'y': [3, [('f', 2), ('g', 1)]], 
'z': [2, [('h', 1), ('i', 1)]]} 

這是我dFinal

{'w': [10, [(5, 'a'), (3, 'b'), (2, 'c')]], 
'x': [5, [(3, 'd'), (2, 'e')]], 
'y': [3, [(2, 'f')]], 
'z': [2, []]} 

,但你可以輕鬆地修復自己。

btw:我會使用函數來使字典和列表解析看起來更容易。現在它是不可讀的。

+0

你爲什麼這樣做:'dict(Counter(v))。items())'??? –

+0

將[['a','a','a','a','a','b','b','b','c','c']'轉換爲[ ('a',5),('b',3),('c',2)]''。 – Elmex80s

+1

您不需要將'Counter'對象轉換爲'dict'對象來執行此操作。只要刪除對「dict」的調用,你會發現它的工作原理完全相同。 –

1

另一種選擇:慢,但更容易理解:

def has_dupe(lst): 
    return any([x[0] > 1 for x in lst[1]]) 

def reduce_list(lst): 
    result = [(x, y) for (x, y) in lst[1] if x > 1] 
    return [sum([x for (x, y) in result]), result] 

d = {key: reduce_list(value) for key, value in d2.items() if has_dupe(value)}