Python - Нахождение каждого вхождения значения в смешанный массив (целые числа, списки) - PullRequest
4 голосов
/ 09 октября 2011

У меня есть массив: x = [ [1, 2], 1, 1, [2, 1, [1, 2]] ] в котором я хочу подсчитать каждое вхождение числа 1 и сохранить это число в переменной one_counter. x.count(1) возвращает только 2 вхождения 1, что недостаточно.

Мой код, приведенный ниже, служит моей цели и хранит 5 в one_counter, однако он выглядит грязно и кажется мне неумным.

Любые предложения, как я могу улучшить его pythonicity и расширить его в более многомерных списках?

Спасибо!

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 ]

8 голосов
/ 09 октября 2011

Вы можете использовать рекурсию:

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
3 голосов
/ 09 октября 2011

Хакерское решение, работающее путем преобразования типа данных в строку: 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))
2 голосов
/ 09 октября 2011

Я думаю, что лучше разделить эту задачу на 2 части.

Часть 1

Часть 1 - создать генератор, который сгладит список ввода.

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

часть 2

Часть 2 - использовать плоский список для подсчета количества вхождений 1 в нем:

print(sum(i==1 for i in flatten_list(x))) 

Выход:

5

Обратите внимание, что i==1 возвращает True, если i=1, и False, если i не равно 1. Но True равно 1 и False равно 0, поэтому sum просто вычисляет количество True случаев (что в данном случае равно 5).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...