Как определить сколько вхождений элемента в двумерный массив Python
Условно, имеется список:
b = [['i', 'are', 'the', 'champignons'], ['we', 'are', 'the', 'champions'], ['champ', 'i']]
Подскажите пожалуйста, как определить: Сколько вхождений каждого элемента по порядку во весь список b (т.е. сколько например элементов i или are во всем списке b)? К примеру, нижеуказанный код очевидно неверный, т.к. он покажет только вхождение элемента i[0] во весь список (а нужно всех элементов), но еще интересует, почему выдается результат 0 вхождений, несмотря на то, что i[0] - это в нашем списке является i, а ее в общем списке 2 штуки.
for i in b:
print(b.count(i[0]))
Пришлось преобразовывать двумерный список b в общий список и потом перебором без проблем все сделал, но понимаю, что это слабовато, т.к. приходится делать лишние движения с преобразованием списков, поэтому хочу узнать, как это можно сделать с исходным списком. При ответе учтите пожалуйста, что мой уровень начальный и ответ должен быть соответствующий, либо ответ может быть любой (для последующего изучения мной материала на эту тему), но с дублированием простого.
Ответы (3 шт):
Нужно просто внимательно разобраться с тем, что в чем нужно считать и в какой переменной что содержится.
Здесь
for i in b: # i - это, например, ['i', 'are', 'the', 'champignons']
print(b.count(i[0]))
считается количество вхождений первого элемента каждого вложенного списка (i[0])в общий список b. Очевидно, что это равно 0. Так как ни один вложенный список не равен 'i'.
Поэтому нужно считать количество вхождений "i" в каждый вложенный список:
for lst in b:
print(lst.count("i"))
Мы можем использовать collections.Counter и itertools.chain из стандартной библиотеки Python:
from collections import Counter
from itertools import chain
b = [['i', 'are', 'the', 'champignons'], ['we', 'are', 'the', 'champions'], ['champ', 'i']]
answer = Counter(chain(*b))
print(answer)
# Counter({'i': 2,
# 'are': 2,
# 'the': 2,
# 'champignons': 1,
# 'we': 1,
# 'champions': 1,
# 'champ': 1})
Здесь chain - это генератор, который возвращает элементы переданных в качестве аргументов итерируемых объектов в порядке их очереди. Распаковав исходный список *b, мы тем самым передаем в chain внутренние списки как самостоятельные последовательности, элементы которых передаются далее в Counter. Там создается словарь, ключами которого служат элементы исходного двумерного списка, а значения - количество их появления во всем двумерном массиве.
В какой-то мере, это можно переписать так:
def count_2D_array(seq: list[list[str]]) -> dict[str, int]:
answer = dict()
for rec in seq:
for item in rec:
answer[item] = answer.get(item, 0) + 1
return answer
b = [['i', 'are', 'the', 'champignons'], ['we', 'are', 'the', 'champions'], ['champ', 'i']]
print(count_2D_array(b))
# {'i': 2, 'are': 2, 'the': 2, 'champignons': 1, 'we': 1, 'champions': 1, 'champ': 1}
def count_2d(lst):
dct = {}
for i in lst:
for j in i:
if j in dct:
dct[j] += 1
else:
dct[j] = 1
return dct