33

次のようなdict内包表記で複数のキー:値のペアを作成しようとしています:

{'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"

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

4

3 に答える 3

35

辞書内包表記は、反復ごとに1 つのキーと値のペアしか生成できません。トリックは、ペアを分離するために追加のループを生成することです。

{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

これは、リストごとに 2 つのキーを繰り返すだけwp_usersなので、同じキーを新しい値で継続的に置き換えていることに注意してください。その場合は、最後のエントリを取得することもできます。

result = dict(zip(('ID', 'post_author'), wp_users[-1]))

ただし、期待する出力は共有されませんでした。

それぞれが 2 つのキーを持つ辞書のリストを作成することを目的とした場合、上記の式のリスト内包表記を各wp_usersエントリに適用する必要があります。

result = [dict(zip(('ID', 'post_author'), e)) for e in wp_users]

2 回目の試行と同じ出力が生成されますが、これで辞書のリストができました。辞書オブジェクトの 1 つに到達するか、さらにループを使用するには、整数インデックスを使用する必要があります。

于 2014-09-12T21:23:52.843 に答える
15

この古い質問に偶然出くわしましたが、受け入れられた答えには納得できません。

受け入れられた回答

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

>>> 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'}
  • の2 回目の反復wp_users, e = (2, 'Bob'), dict は完全に上書きされます{'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'}

それはあなたが望むものではないと思います。

あなたが達成しようとしていることは不明のままですが、2 つのオプションがあります。ユーザー(id, post_author)のリストがあり、辞書のリスト (ユーザーごとに 1 つの辞書) またはタプルの辞書 (フィールドごとに 1 つのタプル) のいずれかを作成します。最初のバージョンは行によるプレゼンテーションとして、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'}
于 2019-03-03T21:12:22.623 に答える
1

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

>>> 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'
>>> 
于 2014-06-02T01:03:24.103 に答える