#python #arrays #for-loop
#python #массивы #для цикла
Вопрос:
У меня есть массив: 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
Комментарии:
1. Какое отношение к этому имеет масштабирование?
2. @IgnacioVazquez-Abrams Я предполагаю, что он злоупотребил словом Scale, возможно, он имел в виду расширение своего типа данных в более размерные списки.
3. @DhruvPathak Да, сэр! Я неправильно понял это для масштаба.
4. Итак, как вы в конечном итоге получили этот список и зачем вам нужно это количество? Все это кажется странно искусственным.
5. @Karl Ты бы расстроился, если бы я сказал, что это я практиковался, наткнулся на дорожный блок и попросил о помощи?
Ответ №1:
Вы могли бы использовать рекурсию:
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
Комментарии:
1. Большое спасибо, Марк! Это имеет смысл, и теперь я лучше понимаю рекурсию вместе с удобством, которым является isinstance().
Ответ №2:
Хакерское решение, работающее путем преобразования типа данных в строку: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))
Ответ №3:
Я думаю, что лучше разделить эту задачу на 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
).
Комментарии:
1. Спасибо, что разбили его. Я действительно ценю это.