关于python:嵌套的list和count()

Nested List and count()

我想知道x出现在嵌套列表中的次数。

如果列表是:

1
2
3
list = [1, 2, 1, 1, 4]
list.count(1)
>>3

这没问题。但如果清单是:

1
list = [[1, 2, 3],[1, 1, 1]]

如何获取1出现的次数?在这种情况下,4.


1
2
3
>>> L = [[1, 2, 3], [1, 1, 1]]
>>> sum(x.count(1) for x in L)
4


这里还有另一种扁平嵌套序列的方法。一旦序列被展平,就可以很容易地检查出项目的计数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def flatten(seq, container=None):
    if container is None:
        container = []

    for s in seq:
        try:
            iter(s)  # check if it's iterable
        except TypeError:
            container.append(s)
        else:
            flatten(s, container)

    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
[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


itertoolscollections模块只得到你需要的东西(用itertools.chain扁平嵌套列表,用collections.Counter计数)。

1
2
3
4
5
import itertools, collections

data = [[1,2,3],[1,1,1]]
counter = collections.Counter(itertools.chain(*data))
print counter[1]

使用递归展平函数而不是itertools.chain展平任意深度的嵌套列表

1
2
3
4
import operator, collections

def flatten(lst):
    return reduce(operator.iadd, (flatten(i) if isinstance(i, collections.Sequence) else [i] for i in lst))

使用了带有operator.iaddreduce而不是sum以便仅构建一次并在适当位置进行更新。


试试这个:

1
reduce(lambda x,y: x+y,list,[]).count(1)

基本上,您从一个空的列表[]开始,并将列表list的每个元素添加到该列表中。在这种情况下,元素本身就是列表,您将得到一个扁平的列表。

附言:在另一个问题上,同样的答案被否决了!

PPS:这个解决方案也被否决了!


检查:计数到任意嵌套深度,处理元组、列表和参数:

1
2
3
4
5
6
7
8
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


如果此列表压缩只能进行一级嵌套展平:

1
2
3
4
>>> L = [[1,2,3],[1,1,1]]
>>> [ item for sublist in L for item in sublist ].count(1)
4
>>>


1
2
3
def nested_count(lst, x):
    return lst.count(x) + sum(
        nested_count(l,x) for l in lst if isinstance(l,list))

此函数返回出现的次数,加上所有包含的子列表中的递归嵌套计数。

1
2
3
>>> data = [[1,2,3],[1,1,[1,1]]]
>>> print nested_count(data, 1)
5