У меня есть некоторые проблемы с чтением вложенной структуры данных из файла .json
через понимание списка.
Это мой файл:
"persons": [
{
"A": [
{
"type": "type1",
"value": "",
"is_valid": true
},
{
"type": "type1",
"value": "",
"is_valid": true
}
]
},
{
"B": [
{
"type": "type2",
"value": "",
"is_valid": true
}
]
},
{
"C": [
{
"type": "type3",
"value": "",
"is_valid": true
},
{
"type": "type3",
"value": "",
"is_valid": false
}
]
}
]
Я хочу прочитать все поля "persons"
и вернуть список объектов Person
.
В настоящее время это мой подход:
def get_all() -> list[Person]:
persons = []
for p in config['persons']:
for key, values in p.items():
for value in values:
persons.append(Person(type=value['type'], name=f'{key}', value='{}'.format(value['value']), is_valid=value['is_valid']))
return persons
Я попытался преобразовать его в понимание списка:
return [[(k, v) for k, v in d.items()] for d in config['persons']]
Но он возвращает список списков.
Мой объект Person
имеет 4 поля:
name: str
type: str
value: str
is_valid: bool
Кроме того, почему вы вообще хотите использовать понимание списка? Это никоим образом не лучше и не читабельнее
Что не так с вашей функцией get_all
? выглядит хорошо для меня
[[ ... ] for ... in ...]
это вложенный список. Зачем ты это написал, если тебе это не нужно? Если вам нужен список Person
объектов, почему вы не написали [Person(...) for ... in ...]
?
«Я пытался преобразовать его в понимание списка... Но он возвращает список списков». - да, список списков пар (k, v)
. Это потому, что а) вы использовали понимание вложенного списка; б) самая внутренняя часть пропускает код, который будет переходить от данных (k, v)
к соответствующим Person
(то есть логике для повторения v
и создания экземпляра класса). Вторая часть тривиальна и может считаться опечаткой (вы просто пропускаете следующий «уровень» понимания списка). Чтобы получить сглаженный результат (вместо списка списков списков Person
), см. связанные дубликаты.
На приведенном ниже рисунке объект person имеет тип list, содержащий config['persons']
return [
(person.keys()[0], type_obj)
for person in persons
for type_obj in person.values()[0]
]
Чтобы продолжить понимание списка, используйте следующий подход:
persons = [Person(name=k, **f)
for d in config['persons'] for k, v in d.items() for f in v]
Обратите внимание, как поле (dict) распаковывается **f
(чтобы соответствовать остальным свойствам объекта)
Пытаться:
>>> [Person(type=value['type'], name=f'{key}', value='{}'.format(value['value']), is_valid=value['is_valid'])
for p in config['persons']
for key, values in p.items()
for value in values]
[Person(type='type1', name='A', value='', is_valid=True),
Person(type='type1', name='A', value='', is_valid=True),
Person(type='type2', name='B', value='', is_valid=True),
Person(type='type3', name='C', value='', is_valid=True),
Person(type='type3', name='C', value='', is_valid=False)]
Какую именно ошибку или нежелательное поведение вы получаете с новым кодом?