web-dev-qa-db-ja.com

辞書内包表記の複数のキーと値のペア

私は次のようなdict内包で複数のkey:valueペアを作成しようとしています:

{'ID': (e[0]), 'post_author': (e[1]) for e in wp_users}

"missing ','"を受け取っています

私もこの方法で試しました:

[{'ID': (e[0]), 'post_author': (e[1])} for e in wp_users]

次に"list indices must be integers, not str"を受け取ります

私は理解していますが、これを修正する最善の方法と、dict内包表記で複数のkey:valueペアが可能かどうかはわかりませんか?

21
mdxprograms

辞書内包表記は、反復ごとにone Key-Valueペアのみを生成できます。トリックは、ペアを分離するために追加のループを生成することです:

{k: v for e in wp_users for k, v in Zip(('ID', 'post_author'), e)}

これは次と同等です。

result = {}
for e in wp_users:
    for k, v in Zip(('ID', 'post_author'), e):
        result[k] = v
22
Martijn Pieters

私はこの古い質問に偶然出くわしましたが、受け入れられた答えに確信が持てません。

受け入れられた答え

受け入れられた答えを邪魔するものは何ですか?このことを考慮:

_>>> wp_users = [(1, 'Bill'), (2, 'Bob')]
>>> {k: v for e in wp_users for k, v in Zip(('ID', 'post_author'), e)}
{'ID': 2, 'post_author': 'Bob'}
_
  • _wp_users_、e = (1, 'Bill')の最初の反復、辞書は_{'ID':1, 'post_author': 'Bill'}_
  • _wp_users_、e = (2, 'Bob')の2回目の反復、辞書は完全に_{'ID':2, 'post_author': 'Bob'}_に上書きされます

イテレーションごとに、ディクトナリのすべての値が上書きされます。ループを回避し、_wp_users_の最後の要素に直接ジャンプできます。

_>>> {k: v for e in wp_users for k, v in Zip(('ID', 'post_author'), e)}
{'ID': 2, 'post_author': 'Bob'}
_

または:

_>>> dict(Zip(('ID', 'post_author'), wp_users[-1]))
{'ID': 2, 'post_author': 'Bob'}
_

それはあなたが望んでいることではないと思います。

あなたが達成しようとしていることは不明確なままですが、ユーザーのリスト_(id, post_author)_があり、辞書のリスト(ユーザーごとに1つの辞書)またはタプルの辞書(1つのタプル)を作成したいという2つのオプションが表示されます。フィールドごと)。最初のバージョンは行によるプレゼンテーションとして、2番目のバージョンは同じデータの列によるプレゼンテーションとして見ることができます。

辞書のリスト

これを試して:

_>>> [dict(Zip(('ID', 'post_author'), user)) for user in wp_users]
[{'ID': 1, 'post_author': 'Bill'}, {'ID': 2, 'post_author': 'Bob'}]
_

userごとに、Zipはタプル_('ID', id)_および_('post_author', author)_を作成し、dictは辞書を生成します。これで、そのようなフィールドにアクセスできます。

_>>> ds = [dict(Zip(('ID', 'post_author'), user)) for user in wp_users]
>>> ds[0]['post_author']
'Bill'
_

タプルの辞書

それはより珍しいですが、値がタプルである1つの辞書が必要になる場合があります。

_>>> dict(Zip(('ID', 'post_author'), Zip(*wp_users)))
{'ID': (1, 2), 'post_author': ('Bill', 'Bob')}
_

Zip(*wp_users)はタプルのリスト[(id1, id2, ...), (post_author1, post_author2, ...)]を作成するだけで、残りは以前のバージョンと同様です。

_>>> d = dict(Zip(('ID', 'post_author'), Zip(*wp_users)))
>>> d['post_author'][0]
'Bill'
_

ボーナス

ラインビューから列を抽出するには:

_>>> [d['ID'] for d in ds]
[1, 2]
_

列ビューから行を抽出するには:

_>>> {k:vs[1] for k, vs in d.items()}
{'ID': 2, 'post_author': 'Bob'}
_
3
jferard

あなたの問題は、2番目のバージョンがone辞書だけでなくlist辞書を作成していることだと思います。文字列を含むリストにアクセスしようとすると、エラーが発生します。

>>> obj = [{'data1': 67, 'data2': 78}]
>>> obj[0]['data1']
67
>>> obj['data1']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list indices must be integers, not str
>>> 

代わりに、 `wp_list [0] ['post_author']として2番目のバージョンにアクセスすると、正常に動作するはずです。

>>> wp_users = ('Bob', 'Joe', 'Sally')
>>> wp_list = [{'ID': (e[0]), 'post_author': (e[1])} for e in wp_users]
>>> wp_list[0]['post_author']
'o'
>>> wp_list[1]['post_author']
'o'
>>> wp_list[2]['post_author']
'a'
>>> 
0
A.J. Uppal