您好我有一个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()
}}
我知道列表理解应该可以解决这个问题,但我仍然坚持如何应对潜在的嵌套。
非常感谢任何帮助。
答案 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