51

csv.DictWriterのfieldnames引数に入力するために、辞書のリストにあるすべてのキーのリストを取得しようとしています。

以前、私はこのようなものを持っていました:

[
{"name": "Tom", "age": 10},
{"name": "Mark", "age": 5},
{"name": "Pam", "age": 7}
]

そして私はfieldnames = list[0].keys()リストの最初の辞書を取り、そのキーを抽出するために使用していました。

今、私はこのようなものを持っており、辞書の1つが他の辞書よりも多くのkey:valueペアを持っています(結果のいずれかである可能性があります)。新しいキーはAPIからの情報に基づいて動的に追加されるため、各辞書で発生する場合と発生しない場合があり、新しいキーがいくつあるかは事前にはわかりません。

[
{"name": "Tom", "age": 10},
{"name": "Mark", "age": 5, "height":4},
{"name": "Pam", "age": 7}
]

fieldnames = list[1].keys()余分なキーを持つのは必ずしも2番目の要素ではないため、私は単に使用することはできません。

簡単な解決策は、キーの数が最も多い辞書を見つけてフィールド名に使用することですが、次のような例がある場合は機能しません。

[
{"name": "Tom", "age": 10},
{"name": "Mark", "age": 5, "height":4},
{"name": "Pam", "age": 7, "weight":90}
]

ここで、2番目と3番目の辞書の両方に3つのキーがありますが、最終結果は実際にはリストになります。["name", "age", "height", "weight"]

4

6 に答える 6

80
all_keys = set().union(*(d.keys() for d in mylist))

編集:リストを解凍する必要があります。修正されました。

于 2012-07-09T16:38:59.113 に答える
27

あなたのデータ:

>>> LoD
[{'age': 10, 'name': 'Tom'}, 
 {'age': 5, 'name': 'Mark', 'height': 4}, 
 {'age': 7, 'name': 'Pam', 'weight': 90}]

この集合の内包的理解はそれを行います:

>>> {k for d in LoD for k in d.keys()}
{'age', 'name', 'weight', 'height'}

このように機能します。まず、dictキーのリストのリストを作成します。

>>> [list(d.keys()) for d in LoD]
[['age', 'name'], ['age', 'name', 'height'], ['age', 'name', 'weight']]

次に、このリストのリストのフラット化されたバージョンを作成します。

>>> [i for s in [d.keys() for d in LoD] for i in s]
['age', 'name', 'age', 'name', 'height', 'age', 'name', 'weight']

そして、重複を排除するためのセットを作成します。

>>> set([i for s in [d.keys() for d in LoD] for i in s])
{'age', 'name', 'weight', 'height'}

これは次のように簡略化できます。

{k for d in LoD for k in d.keys()}
于 2012-07-09T16:47:07.197 に答える
5
from itertools import chain

lis = [
    {"name": "Tom", "age": 10},
    {"name": "Mark", "age": 5, "height":4},
    {"name": "Pam", "age": 7, "weight":90}
]

# without qualification a dict iterates over its keys
# and set takes any iterable in its constructor
headers_as_set = set(chain.from_iterable(lis))

# you asked for a list
headers = list(
    set(chain.from_iterable(lis))
)
于 2018-11-02T03:09:19.673 に答える
3
>>> lis=[
{"name": "Tom", "age": 10},
{"name": "Mark", "age": 5, "height":4},
{"name": "Pam", "age": 7, "weight":90}
]
>>> {z for y in (x.keys() for x in lis) for z in y}
set(['age', 'name', 'weight', 'height'])
于 2012-07-09T16:45:00.177 に答える
2

次の例では、キーを抽出します。

set_ = set()
for dict_ in dictionaries:
    set_.update(dict_.keys())
print set_
于 2012-07-09T16:41:07.980 に答える
2

lis@AshwiniChaudharyの回答から借りて、問題を解決する方法について説明します。

>>> lis=[
{"name": "Tom", "age": 10},
{"name": "Mark", "age": 5, "height":4},
{"name": "Pam", "age": 7, "weight":90}
]

dictを直接反復するとキーが返されるため、キーkeys()を取り戻すために呼び出す必要はなく、リスト内の要素ごとに関数呼び出しとリスト構造を保存できます。

>>> {k for d in lis for k in d}
set(['age', 'name', 'weight', 'height'])

または使用itertools.chain

>>> from itertools import chain
>>> {k for k in chain(*lis)}
set(['age', 'name', 'weight', 'height'])
于 2012-07-09T16:48:52.597 に答える