Python - 在混合数组中查找值的每个出现(整数、列表)
我有一个数组:x = [ [1, 2], 1, 1, [2, 1, [1, 2]] ]
,我想统计数字1
出现的次数,并把这个数字存到变量one_counter
里。用x.count(1)
只能找到2次1
,这不够。
我下面的代码能实现我的目的,并把5
存到one_counter
里,但我觉得它看起来很乱,也不够“python风格”。
有没有什么建议可以让我改进代码,让它更符合python的风格,并且能处理更复杂的多维列表?
谢谢!
x = [[1, 2], 1, 1, [2, 1, [1, 2]]]
one_counter = 0
for i in x:
if type(i) == list:
for j in i:
if type(j) == list:
for k in j:
if k == 1:
one_counter += 1
else:
if j == 1:
one_counter += 1
else:
if i == 1:
one_counter += 1
3 个回答
2
我觉得把这个任务分成两部分会更好。
第一部分
第一部分是创建一个生成器,用来把输入的列表“扁平化”。也就是说,把里面的所有元素都放到一个一维的列表里。
def flatten_list(L):
for i in L:
if isinstance(i,list):
for j in flatten_list(i):
yield j
else:
yield i
测试输出结果:
x = [[1, 2], 1, 1, [2, 1, [1, 2]]]
for i in flatten_list(x):
print i
输出结果:
1
2
1
1
2
1
1
2
第二部分
第二部分是使用扁平化后的列表来计算里面数字 1
出现的次数:
print(sum(i==1 for i in flatten_list(x)))
输出结果:
5
需要注意的是,i==1
如果 i
是 1,就会返回 True
;如果 i
不是 1,就返回 False
。不过,True
在计算时等于 1,而 False
等于 0,所以 sum
这个函数会计算出 True
出现的次数(在这个例子中是 5 次)。
3
这是一个比较“hacky”的解决方案,意思是它有点不太正规,但可以通过把数据类型转换成字符串来工作。你可以在这里查看具体的代码:http://codepad.org/vNEv6B8M
import re
x = [ [1, 2], 1, 1, [2, 1, [1, 2]] ]
nums = [int(i) for i in re.findall(r'\d+', str(x))]
print(nums.count(1))
8
你可以使用递归的方法:
def flatten_count(iterable, element):
count = 0
for item in iterable:
if item == element:
count += 1
if isinstance(item, list):
count += flatten_count(item, element)
return count
或者更简洁一些:
def flatten_count(iterable, element):
return sum(
flatten_count(item, element) if isinstance(item, list) else item == element
for item in iterable
)
用法如下:
>>> x = [[1, 2], 1, 1, [2, 1, [1, 2]]]
>>> print(flatten_count(x, 1))
5