Ведение подсчета в понимании списка python
В Python есть ли counter
во время понимания списка, как это было бы в случае цикла for
?
Было бы более понятно, почему мне нужен счетчик, в этом примере:
Я хочу добиться следующего:
Начальный список: ['p', 'q', 'r', 's']
Желаемый список: [(1, 'P'), (2, 'Q'), (3, 'R'), (4, 'S')]
В нужном списке первый элемент каждого кортежа - порядковые числа. Если бы это был просто плоский список, я мог бы использовать zip
для достижения этого. Но, однако, список, с которым я имею дело, является вложенным, трехуровневым (думаю, иерархические данные), и он генерируется посредством понимания списка.
Итак, мне было интересно, есть ли способ ввести эти порядковые числа во время понимания списка. Если нет, то какое наилучшее возможное решение.
P.S.: Здесь строчные буквы преобразуются в верхний регистр, но это не является частью проблемы, думайте об этом как о простом преобразовании данных.
код:
allObj = Category.objects.all()
tree =[(_, l1.name, [(__, l2.name, [(___, l3.name) for l3 in allObj if l3.parentid == l2.categoryid]) for l2 in allObj if l2.parentid == l1.categoryid]) for l1 in allObj if l1.parentid == None]
allObj
содержит данные из категории таблицы, которые, в свою очередь, содержат иерархические данные, представленные в виде списка привязанностей.
Я поставил _
, где мне нужны порядковые числа. Обратите внимание, что список вложен, так что на каждом уровне будет отдельный счетчик, представляемый 1, 2 и 3 _
s.
Ответы
Ответ 1
Самый простой случай
[(i, x) for i, x in enumerate(some_list, 1)]
Применить фильтр с помощью if-statements
[(i, x) for i, x in enumerate(some_list, 1) if i > 2]
или как это
[(i, x) for i, x in enumerate(some_list, 1) if x != 'p']
Слово совета
Чаще всего вам не нужно это делать. Вместо этого вы просто вызываете enumerate(some_list, 1)
, где требуется перечисление, например, в цикле for
.
Ответ 2
Как уже было показано в других ответах, стандартная библиотека дает вам enumerate
, что означает, что вам, вероятно, даже не нужен список, например:
[(1, 'P'), (2, 'Q'), (3, 'R'), (4, 'S')]
потому что каждый раз, когда вам нужно связать букву с номером, связанным с его положением, вы можете просто позвонить enumerate
.
Пример:
>>> low = ['p', 'q', 'r', 's']
>>> upp = [c.upper() for c in low]
>>>
>>> for i,c in enumerate(upp, 1):
... print(i,c)
...
1 P
2 Q
3 R
4 S
Это был просто пример, возможно, вам действительно нужен этот список.
Ответ 3
RTM: enumerate(['p', 'q', 'r', 's'], 1)
дает вам генератор, дающий (1, 'p'), (2, 'q'), (3, 'r'), (4, 's')
, преобразовать его в list
по вкусу.
Ответ 4
Я искал что-то немного другое, когда я наткнулся на этот ответ.
Мое дело состояло в том, чтобы вести подсчет, основываясь на условии внутри понимания списка.
На всякий случай это полезно кому-то другому, вот как я его решил:
import itertools
counter = itertools.count(0)
[(next(counter), x) for x in some_list if x != 'p']
Таким образом, счетчик будет увеличиваться только при выполнении условия, а не на каждой итерации.
Ответ 5
L = ['p', 'q', 'r', 's']
[(i + 1, x) for i, x in enumerate(L)]
Ответ 6
Помогло бы что-то подобное?
i = 1
y = range(10)
s = [(i + y.index(x), x**2) for x in y]
print s
>>> [(1, 0), (2, 1), (3, 4), (4, 9), (5, 16), (6, 25), (7, 36), (8, 49), (9, 64), (10, 81)]
У меня есть подозрение, что может быть лучший способ сделать это, чем через понимание.
Ответ 7
Я думаю, вы хотите что-то вроде нумерации всех предметов, независимо от уровня гнездования.
Может быть, следующее поможет. Не забудьте создать новый number
для каждого понимания списка. next
может быть записано __next__
в вашей версии Python.
>>> import itertools
>>> number = itertools.count().next
>>> [(number(), [(number(), x + 1) for x in range(y) if x % 2]) for y in range(10) if y % 3]
[(0, []), (1, [(2, 2)]), (3, [(4, 2), (5, 4)]), (6, [(7, 2), (8, 4)]), (9, [(10, 2), (11, 4), (12, 6)]), (13, [(14, 2), (15, 4), (16, 6), (17, 8)])]
Update:
Я знаю, что вам нужно разные счетчики для каждого уровня гнездования. Просто используйте более одного счетчика:
>>> number1 = itertools.count().__next__
>>> number2 = itertools.count().__next__
>>> print([(number1(), [(number2(), x + 1) for x in range(y) if x % 2]) for y in range(10) if y % 3])
[(0, []), (1, [(0, 2)]), (2, [(1, 2), (2, 4)]), (3, [(3, 2), (4, 4)]), (4, [(5, 2), (6, 4), (7, 6)]), (5, [(8, 2), (9, 4), (10, 6), (11, 8)])]
I.e., замените _
на number1()
, как определено выше, __
с number2()
и т.д. Это.