Pythonを使用してjson配列内の特定のキーから値のリストを取得しようとして問題が発生しています。以下のJSONの例を使用して、name
キーの値のみで構成されるリストを作成しようとしています。元のJSON:
[
{
"id": 1,
"name": "Bulbasaur",
"type": [
"grass",
"poison"
]
},
{
"id": 2,
"name": "Ivysaur",
"type": [
"grass",
"poison"
]
}
]
期待される:
["Bulbasaur", "Ivysaur"]
以下は私のアプローチのコードです:
import json
try:
with open("./simple.json", 'r') as f:
contents = json.load(f)
except Exception as e:
print(e)
print(contents[:]["name"])
上記のコードのように、すべてのインデックスをループして追加する必要がないアプローチに移動しようとしています。このアプローチはpythonのjsonライブラリを使用して可能ですか?
これは質問に対する実際の答えではありません。本当の答えは、リスト内包表記を使用することです。ただし、canは、質問で試した構文を具体的に使用できるクラスを作成します。一般的な考え方は、list
をサブクラス化して、[:]
は、リストに特別なビュー(別のクラス)を返します。この特別なビューでは、すべての辞書から同時に検索と割り当てを行うことができます。
class DictView:
"""
A special class for getting and setting multiple dictionaries
simultaneously. This class is not meant to be instantiated
in its own, but rather in response to a slice operation on UniformDictList.
"""
def __init__(parent, slice):
self.parent = parent
self.range = range(*slice.indices(len(parent)))
def keys(self):
"""
Retreives a set of all the keys that are shared across all
indexed dictionaries. This method makes `DictView` appear as
a genuine mapping type to `dict`.
"""
key_set = set()
for k in self.range:
key_set &= self.parent.keys()
return key_set
def __getitem__(self, key):
"""
Retreives a list of values corresponding to all the indexed
values for `key` in the parent. Any missing key will raise
a `KeyError`.
"""
return [self.parent[k][key] for k in self.range]
def get(self, key, default=None):
"""
Retreives a list of values corresponding to all the indexed
values for `key` in the parent. Any missing key will return
`default`.
"""
return [self.parent[k].get(key, default) for k in self.range]
def __setitem__(self, key, value):
"""
Set all the values in the indexed dictionaries for `key` to `value`.
"""
for k in self.range:
self.parent[k][key] = value
def update(self, *args, **kwargs):
"""
Update all the indexed dictionaries in the parent with the specified
values. Arguments are the same as to `dict.update`.
"""
for k in self.range:
self.parent[k].update(*args, **kwargs)
class UniformDictList(list):
def __getitem__(self, key):
if isinstance(key, slice):
return DictView(self, key)
return super().__getitem__(key)
元のコードは、UniformDictList
を1回追加するだけでそのまま使用できます。
import json
try:
with open("./simple.json", 'r') as f:
contents = UniformDictList(json.load(f))
except Exception as e:
print(e)
print(contents[:]["name"])