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']  
    } 

次にIループし、各値がある、新しい辞書を作成します整数とリストの2つの要素を持つリスト整数は、d1のその値の文字列の数です。リストはタプルが含まれ、その文字列をd1に登場D1から(タプルの1位での)文字列と回数を含む各タプル(タプルの位置0に):

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')]  
    } 

を私が削除したいです

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

私は全体の辞書を削除する辞書の理解であると考えているものの例をお読みください。私が望む最後にして、一度だけ(「G」、「H」、および「I」)が表示されます任意の文字列値リストの長さが2未満のアイテム:

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

私はリスト/ディクショナリの理解を把握しようとしており、このようなものを使って私が説明したことを達成し、道に沿って何かを学びたいと考えています。

まず、d2を引数とする関数を書こうとしましたが、各タプルの位置0を参照する方法はわかりません。

次に、d2を変更しようとするのではなく、タプルを持たないd1を使用してdFinalを作成するほうがはるかに簡単だと考えました。

dFinalをd1 および/または d2から作成し、思考プロセスを説明するきれいな方法を説明できれば、本当にありがたいです。どちらも、私が理解のもとに辞書リストを正確に操作する方法を理解するのに役立ちます。

ありがとうございます!

答えて

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

ありがとうございます。私はCounterについて読んで、ここで何が起こっているのか理解しようとします... – 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)}