Создание понимания списка для dict в списке в списке
Мне нужно создать понимание списка, которое извлекает значения из dict в списке в списке, и мои попытки до сих пор не сработали. Объект выглядит так:
MyList=[[{'animal':'A','color':'blue'},{'animal':'B','color':'red'}],[{'animal':'C','color':'blue'},{'animal':'D','color':'Y'}]]
Я хочу извлечь значения для каждого элемента в списке dict / list /, чтобы получить два новых списка:
Animals=[[A,B],[C,D]] Colors=[[blue,red],[blue,Y]]
Какие-либо предложения? Не обязательно использовать понимание списка; это лишь моя отправная точка. Благодаря!
- Python для понимания словарей в словарях?
- Извлечение данных из вложенных диктов и списков
- Построить два списка из списка словарей в python
- создать словарь со списком элементов в виде ключей и их количество в качестве значения
- подсчет символов и строк из файла python 2.7
Animals = [[d['animal'] for d in sub] for sub in MyList] Colors = [[d['color'] for d in sub] for sub in MyList]
Дает желаемый результат:
[['A', 'B'], ['C', 'D']] [['blue', 'red'], ['blue', 'Y']] # No second 'red'.
То, что я здесь сделал, это взять каждый под-список, затем каждый словарь, а затем получить доступ к правильному ключу.
В одном задании (с единственным пониманием списка и с помощью map
и zip
):
Colors, Animals = map(list, zip(*[map(list, zip(*[(d['color'], d['animal']) for d in a])) for a in MyList]))
-Colors, Animals = map(list, zip(*[map(list, zip(*[(d['color'], d['animal']) for d in a])) for a in MyList]))
Если вы в порядке с кортежами, вы можете избежать двух вызовов map => list
EDIT :
Давайте рассмотрим это в некоторых деталях, разложив вложенное понимание. Предположим также, что MyList
имеет m
элементов, для всего n
объектов (словарей).
[[d for d in sub] for sub in MyList]
Это будет проходить через каждый словарь в подсписках. Для каждого из них мы создаем пару с свойством color
в первом элементе и его свойство animal
во втором:
(d['color'], d['animal'])
Пока это займет время, пропорциональное O(n)
– будут обработаны только n
элементов.
print [[(d['color'], d['animal']) for d in sub] for sub in MyList]
Теперь, для каждого из m
подписок в исходном списке, у нас есть один список пар, который нам нужно разархивировать , т. Е. Преобразовать его в два списка одиночных чисел. В Python unzip выполняется с использованием zip
функции, передавая переменное количество кортежей в качестве аргументов (арность первого кортежа определяет количество полученных кортежей). Например, пропуская 3 пары, мы получаем два списка по 3 элемента каждый
>>> zip((1,2), (3,4), (5,6)) #Prints [(1, 3, 5), (2, 4, 6)]
Чтобы применить это к нашему случаю, нам нужно передать массив пар в zip
как переменное число аргументов: это делается с помощью оператора splat , т. Е. *
[zip(*[(d['color'], d['animal']) for d in sub]) for sub in MyList]
Эта операция требует прохождения через каждый подсписчик один раз и, в свою очередь, через каждую из пар, которые мы создали на предыдущем шаге. Таким образом, общее время работы O(n + n + m)
= O(n)
, с приблизительно 2*n + 2*m
операций.
Пока у нас есть m
подписок, каждый из которых содержит два кортежа (первый соберет все цвета для подсписчика, второй – всех животных). Чтобы получить два списка с m
кортежами каждый, мы снова применяем unzip
zip(*[zip(*[(d['color'], d['animal']) for d in sub]) for sub in MyList]
Для этого потребуются дополнительные m
шагов – поэтому время работы будет оставаться O(n)
с приблизительно 2*n + 4*m
операциями.
Для простоты мы не учитывали сопоставление наборов в списках в этом анализе – это нормально, если вы в порядке с кортежами.
Однако кортежи неизменяемы, так что это может быть не так. Если вам нужны списки списков, вам нужно применить функцию list
к каждому кортежу: один раз для каждого из сублистов m
(всего 2*n
элементов) и один раз для каждого из 2 списков первого уровня, то есть животных и Цвета (каждый из которых содержит по m
элемента). Для подсчета list
требуется время, пропорциональное длине последовательности, к которой оно применяется, для этого дополнительного шага требуются операции 2*n + 2*m
, которые все еще O(n)
.
- Получить строку перед шаблоном, который не будет соответствовать шаблону
- Объект 'list' не имеет атрибута 'get'