Python - 在混合数组中查找值的每个出现(整数、列表)

4 投票
3 回答
578 浏览
提问于 2025-04-17 03:58

我有一个数组: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

撰写回答