Как разобрать JSON, чтобы получить все значения конкретного ключа в массиве? - PullRequest
0 голосов
/ 16 мая 2019

У меня проблемы с попыткой получить список значений из определенного ключа в массиве json, используя python.Используя приведенный ниже пример 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?

Ответы [ 3 ]

1 голос
/ 16 мая 2019

Попробуйте это с списком :

print([d["name"] for d in contents])
1 голос
/ 17 мая 2019

Это не настоящий ответ на вопрос. Реальный ответ - использовать понимание списка. Однако вы можете создать класс, который позволит вам использовать именно тот синтаксис, который вы использовали в вопросе. Общая идея состоит в том, чтобы создать подкласс 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:

import json
try:
    with open("./simple.json", 'r') as f:
        contents = UniformDictList(json.load(f))
except Exception as e:
    print(e)

print(contents[:]["name"])
1 голос
/ 16 мая 2019

Вы не можете сделать contents[:]["name"], так как contents - это список словарь с целочисленными индексами, и вы не можете получить доступ к элементу из него, используя строку name.

Чтобы исправить это, вы должныхотите перебрать список и получить значение ключа name для каждого item

import json
contents = []

try:
    with open("./simple.json", 'r') as f:
        contents = json.load(f)
except Exception as e:
    print(e)


li = [item.get('name') for item in contents]
print(li)

Вывод будет

['Bulbasaur', 'Ivysaur']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...