2016-06-02 7 views
0

が、私はfolowingフォームのリストを持っている:一覧 - 例外TypeError:非ハッシュタイプ: '辞書'

oldlist = [{'x': {'a':1,'b':2}, 'y':2},{'x':{'a':6,'b':7}, 'y':2},{'x':{'a':1,'b':2}, 'y':3},{'x':{'a':1,'b':2}, 'y':2},{'x':{'a':10,'b':11}, 'y':4}] 

final = [{'x':{'a':1,'b':2},'y':[2,3,2],'count':3},{'x':{'a':6,'b':7},'y':[2],'count':1},{'x':{'a':10,'b':11},'y':[4],'count':1}] 

に変換する

私は

を試してみました
oldlist = [{'x': {'a':1,'b':2}, 'y':2},{'x':{'a':6,'b':7}, 'y':2},{'x':{'a':1,'b':2}, 'y':3},{'x':{'a':1,'b':2}, 'y':2},{'x':{'a':10,'b':11}, 'y':4}] 
list1=[] 
list2=[] 
list3=[] 
s = set([d['x'] for d in oldlist]) 
news=list(s) 
for item in oldlist: 
if item['x'] == news[0]: 
     list1.append(item['y']) 

if item['x'] == news[1]: 
     list2.append(item['y']) 

if item['x'] == news[2]: 
     list3.append(item['y']) 
final=[] 
dic1 = {'x':news[0],'y':list1,'count':len(list1)} 
dic2 = {'x':news[1],'y':list2,'count':len(list2)} 
dic3 = {'x':news[2],'y':list3,'count':len(list3)} 
final.append(dic1) 
final.append(dic2) 
final.append(dic3) 
print final 

取得

s = set([d['x'] for d in oldlist])
TypeError: unhashable type: 'dict'

これを行う簡単な方法はありますか?ここで私はxが3つの値しか持てないことを知っていたので、3つの変数list1、list2、list3を作成しました。 xが他にもいくつかの値を持つことができ、私はfinalのような辞書の同様のリストを見つけなければなりません!それはまた、文字列のために働く必要があります!

編集:これを試しました。しかし、それはすべての非ハッシュの種類がある集合関数は文字列のみ、番号、

データ型リストのようなタプルなど、辞書のように、hashableオブジェクトを扱うことができ、ひいてはセット機能はできません

s = list(frozenset(oldlist[0]['x'].items())) 
print s 
for item in oldlist: 
    s.append(frozenset(item['x'].items())) 
+0

エラーが –

答えて

1

あなたはキーがxの値から作成されたfrozensetオブジェクトがであるdefaultdictを使用することができます。

は、このコードを試してみてください(第五第六ラインにコメントを詳しく見てみましょう)元のdictsと値は相対yのリストです。次に、リスト内包して最終結果を構築することができ、バックdictsにfrozensetsを回す:

from collections import defaultdict 

oldlist = [{'x': {'a':1,'b':2}, 'y':2},{'x':{'a':6,'b':7}, 'y':2},{'x':{'a':1,'b':2}, 'y':3},{'x':{'a':1,'b':2}, 'y':2},{'x':{'a':10,'b':11}, 'y':4}] 
res = defaultdict(list) 
for d in oldlist: 
    res[frozenset(d['x'].items())].append(d['y']) 

final = [{'x': dict(k), 'y': v, 'count': len(v)} for k, v in res.items()] # [{'y': [2, 3, 2], 'x': {'a': 1, 'b': 2}, 'count': 3}, {'y': [4], 'x': {'a': 10, 'b': 11}, 'count': 1}, {'y': [2], 'x': {'a': 6, 'b': 7}, 'count': 1}] 
+0

私はこれが出てくると思ってくれてありがとう! – glitterati

+0

このトリックを知らなかった –

+0

@DeanChristianArmada:もう1つの方法は、dictの項目をタプルのタプルに変換することですが、その場合はdictsが順序付けされていないのでソートする必要があります。 '(' a '、1)、(' b '、2)] 'または' [(' b '、2)を返します。 、( 'a'、1)] ' – niemmi

3

めちゃくちゃましたそれらを扱う。

What do you mean by hashable in Python?

http://blog.lerner.co.il/is-it-hashable-fun-and-games-with-hashing-in-python/

あなたが必要なものの基本的な実装:

for elem in oldlist: 
    found = False 
    for item in newlist: 
     if elem['x'] == item['x']: 
      y = item.get('y',[]) 
      item['y'] = t.append(elem['y']) 
      found = True 
      break 
    if not found: 
     newlist.append({'x':elem['x'], 'y':[elem['y']]}) 

これはあなたに期待した結果が得られます

+0

スローされた回線を共有することができればそれは参考になります次に何の変更私は自分のコードにすることができますそれを動作させる? – glitterati

+0

@glitterati:これのための特定のalgoを把握することはできません。通常のブルートフォース方法で行う必要があります –

+0

「通常のブルートフォース方法」とは何ですか?私の仕事はうまくいかない! – glitterati

1

セットのいくつかのより明確にするために

Pythonの関数は何もしません辞書を許可して強制することはできません。代わりに別の方法を試してください。

oldlist = [{'x': {'a':1,'b':2}, 'y':2},{'x':{'a':6,'b':7}, 'y':2},{'x':{'a':1,'b':2}, 'y':3},{'x':{'a':1,'b':2}, 'y':2},{'x':{'a':10,'b':11}, 'y':4}] 
list1=[] 
list2=[] 
list3=[] 
s = [d['x'] for d in oldlist] # Placed the dictionaries in a list 
s = result = [dict(tupleized) for tupleized in set(tuple(item.items()) for item in s)] # This is the manual way on removing duplicates dictionaries in a list instead of using set 
news=list(s) 
for item in oldlist: 
    if item['x'] == news[0]: 
     list1.append(item['y']) 

    if item['x'] == news[1]: 
     list2.append(item['y']) 

    if item['x'] == news[2]: 
     list3.append(item['y']) 

final=[] 
dic1 = {'x':news[0],'y':list1,'count':len(list1)} 
dic2 = {'x':news[1],'y':list2,'count':len(list2)} 
dic3 = {'x':news[2],'y':list3,'count':len(list3)} 
final.append(dic1) 
final.append(dic2) 
final.append(dic3) 
print final 
+0

ありがとう!これはうまくいきますが、xについてはoldlistに3つの不確定な値しかないことがわかっているので、list1 list2とlist 3を割り当てることができます。あなたは何かを提案できますか? – glitterati

+0

ちょうどあなたのコメントを見ましたが、私は変更のための私の答えに投票できますか? –

関連する問題