Python遍历列表并计算某个值的项目

时间:2012-12-10 20:11:43

标签: python

您好我有一个python问题,我必须计算哪个列表元素包含值2,在具有不同级别的嵌套的列表中。 E.g:

my_list = [[2,3,2,2], [[2,1,2,1], [2,1,1]], [1,1,1]]

此列表最多可以有三个嵌套级别,但也可以是两个级别或只有一个级别。

我有一段有用的代码:

count = 0
for i in my_list:
    if len(i) > 1:
        for x in i:
            if 2 in x:
                count += 1
    elif i == 2:
        count += 1

然而,除了非常丑陋之外,这并没有考虑到列表中包含单个元素2的可能性。它也无法在单个{{1}上获得len() }}

我知道列表理解应该可以解决这个问题,但我仍然坚持如何应对潜在的嵌套。

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:7)

我使用了来自https://stackoverflow.com/a/2158532/367273

flatten()生成器的变体

原始产生来自任意嵌套和不规则形状的可迭代结构的每个元素。我的变体(下面)产生了最里面的迭代,而不是产生标量。

from collections import Iterable

def flatten(l):
    for el in l:
        if isinstance(el, Iterable) and any(isinstance(subel, Iterable) for subel in el):
            for sub in flatten(el):
                yield sub
        else:
            yield el

my_list = [[2,3,2,2], [[2,1,2,1], [2,1,1]], [1,1,1]]
print(sum(1 for el in flatten(my_list) if 2 in el))

对于您的示例,它会打印3

答案 1 :(得分:0)

更新和最终答案:

我的解决方案会递归嵌套的列表列表。如果列表包含2,则计数设置为1。然后添加任何子列表的计数总和。此方法支持异构列表,其中数字和列表可以在同一级别混合,如下面的第二个用法示例所示:

import collections

def list_count(l):
    count = int(2 in l)
    for el in l:
        if isinstance(el, collections.Iterable):
            count += list_count(el)
    return count

以下是几个测试用例:

my_list = [[2,3,2,2], [[2,1,2,1], [2,1,1]], [1,1,1]]
print = list_count(my_list)
# 3 is printed

my_list = [2, [2,3,2,2], [[2,1,2,1], [2,1,1]], [1,1,1]]
print = list_count(my_list)
# 4 is printed

@ Akavall的回答提醒我,这可能会被折叠成一个单行。 (但是,当我这样做的时候,我总是得到(通常是合理的)关于SO的可读性投诉。)

def list_count(l):
    return ( int(2 in l) +
        sum([list_count(el) for el in l 
            if isinstance(el, collections.Iterable)]) )

原始答案(不是原始问题所寻找的)

更新:@NPE在指定预期结果后更新了他的答案。他现在的答案就像原版海报所希望的一样。

@ NPE的(原创)答案很接近,但你问:

  

计算哪些列表元素包含值2

我在需要时阅读:

my_list = [[2,3,2,2], [[2,1,2,1], [2,1,1]], [1,1,1]]
print(sum([1 for e in [flatten(sl) for sl in ml] if 2 in e]))

但他正在寻找3。我的代码生成2,因为它遍历每个顶级元素并计算它是否包含任何2,但这不是他真正想要的。

答案 2 :(得分:0)

这是另一种方法:

small_list = [2]
my_list = [[2,3,2,2], [[2,1,2,1], [2,1,1]], [1,1,1]]
another_list = [[2,3,2,2], [[2,1,2,1], [2,1,1]], [1,1,1], 2]

from collections import Iterable 

def count_lists_w_two(x):
    if isinstance(x, Iterable) == False:
        return 0
    else:
        return (2 in x) + sum(count_lists_w_two(ele) for ele in x)

结果:

>>> count_lists_w_two(small_list)
1
>>> count_lists_w_two(my_list)
3
>>> count_lists_w_two(another_list)
4