In Python, is there any counter
available during the list comprehension as it would be in case of a for
loop?
It would be more clear why I need a counter, with this example:
I wish to achieve the following:
Initial List: ['p', 'q', 'r', 's']
Desired List: [(1, 'P'), (2, 'Q'), (3, 'R'), (4, 'S')]
In the desired list, first element of every tuple are ordinal numbers. If it were just flat list, I could have used zip
to achieve this. But however, the list I am dealing with is nested, three level deep (think of hierarchical data), and it is generated through list comprehension.
So, I was wondering is there any way to introduce those ordinal numbers during list comprehension. If not, what would be the best possible solution.
P.S. : Here the lower case letters are converted to uppercase, but that is not a part of problem, think of it as just a data conversion.
Code:
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
contains data from table category, which in turn contains hierarchical data represented in the form of Adjacency List.
I have put _
where I need ordinal numbers to be. Notice that the list is nested, so there will be a separate counter at each level represented by 1, 2 & 3 _
s.
Yes, the list comprehension preserves the order of the original iterable (if there is one). If the original iterable is ordered (list, tuple, file, etc.), that's the order you'll get in the result. If your iterable is unordered (set, dict, etc.), there are no guarantees about the order of the items.
The most straightforward way to get the number of elements in a list is to use the Python built-in function len() . As the name function suggests, len() returns the length of the list, regardless of the types of elements in it.
Short answer: you can count the number of elements x that match a certain condition(x) by using the one-liner expression sum(condition(x) for x in lst) . This creates a generator expression that returns True for each element that satisfies the condition and False otherwise.
[(i, x) for i, x in enumerate(some_list, 1)]
[(i, x) for i, x in enumerate(some_list, 1) if i > 2]
or like this
[(i, x) for i, x in enumerate(some_list, 1) if x != 'p']
Most often you don't need to do this. Instead you just call enumerate(some_list, 1)
where the enumeration is needed, in a for
loop for example.
I was looking to something slightly different when I stumbled upon this answer.
My case was to keep a count based on a condition inside the list comprehension. Just in case it's useful to someone else, this is how I solved it:
import itertools counter = itertools.count(0) [(next(counter), x) for x in some_list if x != 'p']
In this way the counter will only be incremented when the condition is met and not at every iteration.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With