2011-07-11 20 views
2

私は彼らの異なる値を考慮に入れて、私は辞書のリストに再編成したい別の辞書を持っている:その値に応じて辞書のリストに辞書を変換

辞書:

[{'language': 'de', 'suggestion': 'fressen', 'comment': 'for animals'}, 
{'language': 'de', 'suggestion': 'essen', 'comment': ''}, 
{'language': 'fr', 'suggestion': 'manger', 'comment': ''}, 
{'language': 'fr', 'suggestion': 'bouffer', 'comment': 'slang'}] 

リスト辞書の:

[{'language': 'de', 'suggestion': ['fressen', 'essen'], 'comment': ['for animals', '']}, \ 
{'language': 'fr', 'suggestion': ['manger', 'bouffer'], 'comment': ['', 'slang'}] 

私はまだPythonの初心者です、と私は同じ「言語」を持つグループに、すべての辞書を開始する場所がわからない:「デ」へ同じdict。

+4

あなたの最初のデータを構造(dictsのリスト)は合理的です:オブジェクトのリストやデータベースの行のリストに似ています。あなたの2番目のデータ構造はうまくいくと思われます。なぜなら、 'iith'の提案を' ith'コメントと同期させなければならない並列配列になるからです。言葉自体を第2レベルのキー(fressen、essenなど)として、トップレベルのキー(「de」、「fr」など)として言語を使用して、dictsのdictを考えましたか?値としてのコメント? – FMc

+0

実際には、{{dictionary.language}}を使用するために、そのような辞書をテンプレートに簡単に使用できるようにしたいだけです。私は実際には、キーが動的である場合、どのようにコンテンツをレンダリングするのか分からない。 – Edouard

答えて

4

簡単な解決、その長い1行を使用して、ネストされた内包表記ですべてを行います。

出力:reduceを使用して

{'de': {'essen': '', 'fressen': 'for animals'}, 
'fr': {'bouffer': 'slang', 'manger': ''}} 
1

少し複雑ソリューション、それにもかかわらず:

>>> dicts = [{'language': 'de', 'suggestion': 'fressen', 'comment': 'for animals'}, 
... {'language': 'de', 'suggestion': 'essen', 'comment': ''}, 
... {'language': 'fr', 'suggestion': 'manger', 'comment': ''}, 
... {'language': 'fr', 'suggestion': 'bouffer', 'comment': 'slang'}] 
>>> main_key = 'language' 
>>> result_dict = dict() 
>>> for d in dicts: 
...  for key, value in d.iteritems(): 
...    if key == main_key: 
...      result_dict.setdefault(d[main_key], dict())[main_key] = value 
...    else: 
...      result_dict.setdefault(d[main_key], dict()).setdefault(key, list()).append(value) 
... 
>>> result_dict.values() 
[{'comment': ['', 'slang'], 'language': 'fr', 'suggestion': ['manger', 'bouffer']}, {'comment': ['for animals', ''], 'language': 'de', 'suggestion': ['fressen', 'essen']}] 

私たちは、このキーでリスト内の他のすべての辞書に参加main_key値を上基づか。

ld = [{'language': 'de', 'suggestion': 'fressen', 'comment': 'for animals'}, 
{'language': 'de', 'suggestion': 'essen', 'comment': ''}, 
{'language': 'fr', 'suggestion': 'manger', 'comment': ''}, 
{'language': 'fr', 'suggestion': 'bouffer', 'comment': 'slang'}] 

langs = {i['language'] for i in ld} 

d = [] 

for lang in langs: 
    d.append({"language": lang}) 
    for key in ld[0].keys() - ["language"]: 
     d[-1][key] = [i[key] for i in ld if i["language"] == lang] 

print(d) 

出力::

[{'comment': ['', 'slang'], 
    'language': 'fr', 
    'suggestion': ['manger', 'bouffer']}, 
{'comment': ['for animals', ''], 
    'language': 'de', 
    'suggestion': ['fressen', 'essen']}] 

あなたがあなたの質問に彼のコメントに記述さFMCのデータ構造@使用することを選択した場合、すべてのdictsのキーが同じであると仮定し

1

はあなたにクリーンなマージの分離およびマージ・ロジックいます:

#!/usr/bin/env python 

from pprint import pprint 
from collections import defaultdict 

def group(grouped, ungrouped): 
    group = grouped[ungrouped['language']] 
    group['language'] = ungrouped['language'] 
    group['suggestion'].append(ungrouped['suggestion']) 
    group['comment'].append(ungrouped['comment']) 
    return grouped 

ungrouped = [{'language': 'de', 'suggestion': 'fressen', 'comment': 'for animals'}, 
      {'language': 'de', 'suggestion': 'essen', 'comment': ''}, 
      {'language': 'fr', 'suggestion': 'manger', 'comment': ''}, 
      {'language': 'fr', 'suggestion': 'bouffer', 'comment': 'slang'}] 

grouped = reduce(group, ungrouped, defaultdict(lambda: defaultdict(list))).values() 

# Convert defaultdict to dict for pretty printing. 
pprint([dict(group) for group in grouped]) 
+0

+1:非常にpythonicではありませんが、かなり機能的な解決策です。 – phant0m

1

ない非常にニシキヘビを、それも動作します:

data = [{'language': 'de', 'suggestion': 'fressen', 'comment': 'for animals'}, 
{'language': 'de', 'suggestion': 'essen', 'comment': ''}, 
{'language': 'fr', 'suggestion': 'manger', 'comment': ''}, 
{'language': 'fr', 'suggestion': 'bouffer', 'comment': 'slang'}] 

def prepare(inputData): 
    outputData = [] 
    if inputData and isinstance(inputData[0], dict) and inputData[0].get('language'): 
     keys = inputData[0].keys() 
     del keys[keys.index('language')] 
    else: 
     #do something - raise issue or return 
     return outputData 
    for l in set(line['language'] for line in inputData): 
     langData = {"language": l} 
     langData.update([(k, [line[k] for line in inputData if line["language"] == l]) for k in keys]) 
     outputData.append(langData) 
    return outputData 

prepare(data)