1

私は次のような辞書を持っています:

{ ('name', 'user1'): 'foo',
  ('user', 'user1'): 'bar',
  ('name', 'user2'): 'bat',
  ('user', 'user2'): 'baz' }

そして、私は次のように変換したいと思います:

{ 'user1': {'name': 'foo', 'user': 'bar'}, 
  'user2': {'name': 'bat', 'user': 'baz'} }

これはデフォルトの辞書で簡単に実行できますが、辞書内包表記を使用したいと思います。

これまでのところ、私は持っています:

{user: {key:value for (key, user), value in my_dict.items()}}

しかし、ユーザーはループ内にないため、name 'user' is not definedエラーになります。

どうすれば辞書理解でこれを達成できますか?

4

2 に答える 2

3

キーと値の両方がシーケンス内の項目と直接 1 対 1 の関係にある場合は、dict 内包表記を使用できます。

ただし、出力値は入力シーケンスの複数のエントリに基づいています。タプル キーで項目を 1 秒あたりのシーケンス値にグループ化できない場合は、defaultdictセットアップを使用する必要があります。

グループ化は確かに可能ですが、ソートが必要になるため、プラスループソリューションitertools.groupby()と比較してパフォーマンスが低下します。defaultdict

使用itertools.groupby:

from itertools import groupby

user = lambda item: item[0][1]

{user: {key[0]: value for key, value in grouped}
    for user, grouped in groupby(sorted(my_dict.items(), key=user), key=user)}

出力デモ:

>>> {user: {key[0]: value for key, value in grouped}
...     for user, grouped in groupby(sorted(my_dict.items(), key=user), key=user)}
{'user2': {'name': 'bat', 'user': 'baz'}, 'user1': {'name': 'foo', 'user': 'bar'}}

これは、ソリューションの O(n) 複雑さに対して、O(n log n) ソリューションdefaultdictです。

from collections import defaultdict

output = defaultdict(dict)

for (key, user), value in my_dict.iteritems():
    output[user][key] = value
于 2013-05-07T18:12:45.300 に答える
0

これはうまくいきます:

from __future__ import print_function
from itertools import groupby
from operator import itemgetter 

d=dict({('name', 'user1'): 'foo', ('user', 'user1'): 'bar',
        ('name', 'user2'): 'bat',
        ('user', 'user2'): 'baz' })

l = []
for key, val in d.items() :
    l.append([key[1], key[0], val])

l.sort(key=itemgetter(0))

d_ = dict()
for key, group in groupby(l, lambda x: x[0]):
    dic = dict()
    for thing in group:
        dic[thing[1]] = thing[2]
    d_[key] = dic

itertools の groupby は、リストが以前にソートされている場合にのみ機能することに注意してください。

于 2013-05-07T20:23:16.103 に答える