Вложенный список и счетчик()
Я хочу получить количество раз x во вложенном списке.
если список:
list = [1, 2, 1, 1, 4]
list.count(1)
>>3
Это нормально. Но если список:
list = [[1, 2, 3],[1, 1, 1]]
Как я могу получить количество раз 1? В этом случае 4.
Ответы
Ответ 1
Вот еще один подход к сглаживанию вложенной последовательности. После того, как последовательность будет сплющена, легко проверить количество элементов.
def flatten(seq,container=None):
if container is None:
container = []
for s in seq:
if hasattr(s,'__iter__'):
flatten(s,container)
else:
container.append(s)
return container
c = flatten([(1,2),(3,4),(5,[6,7,['a','b']]),['c','d',('e',['f','g','h'])]])
print c
print c.count('g')
d = flatten([[[1,(1,),((1,(1,))), [1,[1,[1,[1]]]], 1, [1, [1, (1,)]]]]])
print d
print d.count(1)
Вышеприведенный код печатает:
[1, 2, 3, 4, 5, 6, 7, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
1
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
12
Ответ 2
>>> L = [[1, 2, 3], [1, 1, 1]]
>>> sum(x.count(1) for x in L)
4
Ответ 3
Модули itertools
и collections
получили только то, что вам нужно (сгладить вложенные списки itertools.chain
и подсчитать с помощью collections.Counter
import itertools, collections
data = [[1,2,3],[1,1,1]]
counter = collections.Counter(itertools.chain(*data))
print counter[1]
Используйте рекурсивную функцию сглаживания вместо itertools.chain
, чтобы сгладить вложенные списки произвольной глубины уровня
import operator, collections
def flatten(lst):
return reduce(operator.iadd, (flatten(i) if isinstance(i, collections.Sequence) else [i] for i in lst))
reduce
с operator.iadd
использовался вместо sum
, так что сплющенный строится только один раз и обновляется на месте
Ответ 4
Попробуйте следующее:
reduce(lambda x,y: x+y,list,[]).count(1)
В принципе, вы начинаете с пустого списка []
и добавляете к нему каждый элемент списка list
. В этом случае элементы сами являются списками, и вы получаете сплющенный список.
PS: Только что получил ответ на подобный ответ в другом вопросе!
PPS: для этого решения тоже было принято!
Ответ 5
Для этого: подсчитайте любую произвольную глубину вложенности, обработайте кортежи, списки и аргументы:
hits = lambda num, *n: ((1 if e == num else 0)
for a in n
for e in (hits(num, *a) if isinstance(a, (tuple, list)) else (a,)))
lst = [[[1,(1,),((1,(1,))), [1,[1,[1,[1]]]], 1, [1, [1, (1,)]]]]]
print sum(hits(1, lst, 1, 1, 1))
15
Ответ 6
Если с этим списком может быть только один уровень сглаживания вложенности:
>>> L = [[1,2,3],[1,1,1]]
>>> [ item for sublist in L for item in sublist ].count(1)
4
>>>
Ответ 7
def nested_count(lst, x):
return lst.count(x) + sum(
nested_count(l,x) for l in lst if isinstance(l,list))
Эта функция возвращает количество вхождений, а также рекурсивный вложенный счет во всех содержащихся под списках.
>>> data = [[1,2,3],[1,1,[1,1]]]
>>> print nested_count(data, 1)
5