Создать словарь из двух списков, используя объект 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)) создать список с количеством элементов для каждого списка n1
  • zip объединяет два списка
Другие вопросы по тегам