Создать словарь из двух списков, используя объект Counter
У меня есть следующий список:
name = ["Anne", "Jack", "Mary"]
У меня также есть вложенный список, где каждый элемент является другим списком и связан с именем, присутствующим в индексе name
список. Это показано ниже:
n1 = [[0, 0, 3], [0, 5, 5], [1, 3, 3]]
Таким образом, для 'Anne'
, первый элемент в списке name
, список из n1
связано с ним является первым элементом [0, 0, 3]
,
Точно так же для "Jack"
, второй элемент в списке name
, список из n1
связано с этим является вторым элементом [0, 5, 5]
, и так далее.
Я хочу посчитать вхождение каждого числа в каждом элементе n1
и подключить его к именам в name
список в формате словаря.
Поэтому я хочу, чтобы мой вывод выглядел следующим образом:
{'Anne': {'0': 2, '3': 1}, 'Jack': {'0': 1, '5': 2}, 'Mary': {'1': 1, '3': 2}}
Я попробовал ниже:
from collections import Counter
clust = {}
for val in name:
clust[val] = {}
for e in n1:
wc = Counter(str(e1) for e1 in e)
clust[val] = dict(wc)
Но это дает мне вывод:
clust = {'Anne': {'1': 1, '3': 2}, 'Jack': {'1': 1, '3': 2}, 'Mary': {'1': 1, '3': 2}}
Что неверно. Как мне получить желаемый результат?
5 ответов
Вам необходимо сопоставить данные из n1
с каждым предметом в name
; самый простой способ с zip
:
>>> from collections import Counter
>>> name = ["Anne", "Jack", "Mary"]
>>> n1 = [[0,0,3], [0,5,5], [1,3,3]]
>>> {name_: Counter(data) for name_, data in zip(name, n1)}
{'Anne': Counter({0: 2, 3: 1}), 'Jack': Counter({5: 2, 0: 1}), 'Mary': Counter({3: 2, 1: 1})}
(Обратите внимание на использование "словарного понимания", см. Документы.)
Если ключи в вашем Counter
Быть строкой имеет решающее значение, вы можете использовать map
преобразовать целые числа перед подсчетом:
>>> {name_: Counter(map(str, data)) for name_, data in zip(name, n1)}
{'Anne': Counter({'0': 2, '3': 1}), 'Jack': Counter({'5': 2, '0': 1}), 'Mary': Counter({'3': 2, '1': 1})}
Для каждого имени ваш for e in n1:
зацикливание на всех элементах n1, создание счетчика для каждого из них и установка clust[val]
к результату. Так clust[val]
заканчивается как результат только последнего элемента в n1
,
Вы должны использовать zip()
объединить два списка name и n1 в один, или, возможно, лучше, список имен и результирующие счетчики из n1. zip()
возвращает кортежи с элементами, взятыми из обоих списков (zip([1, 2], ['a', 'b']) becomes [(1, 'a'), (2, 'b')]
, Вы можете сделать dict
из таких кортежей напрямую.
Так:
clust = dict(zip(name, [Counter(e) for e in n1]))
Просто используйте значение индекса name
список для подсчета предметов в n1
подсписок. Это можно сделать с помощью enumerate(name)
, Возвращает значение и его индекс. Используйте этот возвращаемый индекс для подсчета элементов в n1
подсписок, соответствующий пункту в name
,
>>> from collections import Counter
>>> name = ["Anne", "Jack", "Mary"]
>>> n1 = [[0,0,3], [0,5,5], [1,3,3]]
>>> clust = {}
>>> for i,val in enumerate(name):
... wc = Counter(str(e1) for e1 in n1[i])
... clust[val] = dict(wc)
...
>>> clust
{'Anne': {'0': 2, '3': 1}, 'Jack': {'0': 1, '5': 2}, 'Mary': {'1': 1, '3': 2}}
Вы должны получить это так
from collections import Counter
name = ["Anne", "Jack", "Mary"]
n1 = [[0,0,3], [0,5,5], [1,3,3]]
clust = {name[i]: Counter(n1[i]) for i in range(len(name))}
Выход:
{'Anne': Counter({0: 2, 3: 1}),
'Jack': Counter({5: 2, 0: 1}),
'Mary': Counter({3: 2, 1: 1})}
Вот один вкладыш, чтобы получить желаемый результат:
zip(name, [dict(Counter(z)) for z in [[str(y) for y in x] for x in n1]])
Чтобы сломать это:
[[str(y) for y in x] for x in n1]
преобразует элементы n1 в списокdict(Counter(z))
создать список с количеством элементов для каждого списка n1zip
объединяет два списка