Double Iteration in List Comprehension
Gee, I guess I found the anwser: I was not taking care enough about which loop is inner and which is outer. The list comprehension should be like:
[x for b in a for x in b]
to get the desired result, and yes, one current value can be the iterator for the next loop.
python list comprehension double for
Lets break it down.
A simple list-comprehension:
[x for x in collection]
This is easy to understand if we break it into parts: [A for B in C]
A
is the item that will be in the resulting listB
is each item in the collectionC
C
is the collection itself.
In this way, one could write:
[x.lower() for x in words]
In order to convert all words in a list to lowercase.
It is when we complicate this with another list like so:
[x for y in collection for x in y] # [A for B in C for D in E]
Here, something special happens. We want our final list to include A
items, and A
items are found inside B
items, so we have to tell the list-comprehension that.
A
is the item that will be in the resulting listB
is each item in the collectionC
C
is the collection itselfD
is each item in the collectionE
(in this case, alsoA
)E
is another collection (in this case,B
)
This logic is similar to the normal for loop:
for y in collection: # for B in C:
for x in y: # for D in E: (in this case: for A in B)
# receive x # # receive A
To expand on this, and give a great example + explanation, imagine that there is a train.
The train engine (the front) is always going to be there (the result of the list-comprehension)
Then, there are any number of train cars, each train car is in the form: for x in y
A list comprehension could look like this:
[z for b in a for c in b for d in c ... for z in y]
Which would be like having this regular for-loop:
for b in a:
for c in b:
for d in c:
...
for z in y:
# have z
In other words, instead of going down a line and indenting, in a list-comprehension you just add the next loop on to the end.
To go back to the train analogy:
Engine
- Car
- Car
- Car
... Tail
What is the tail? The tail is a special thing in list-comprehensions. You don't need one, but if you have a tail, the tail is a condition, look at this example:
[line for line in file if not line.startswith('#')]
This would give you every line in a file as long as the line didn't start with a hashtag (#
), others are just skipped.
The trick to using the "tail" of the train is that it is checked for True/False at the same time as you have your final 'Engine' or 'result' from all the loops, the above example in a regular for-loop would look like this:
for line in file:
if not line.startswith('#'):
# have line
please note: Though in my analogy of a train there is only a 'tail' at the end of the train, the condition or 'tail' can be after every 'car' or loop...
for example:
>>> z = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
>>> [x for y in z if sum(y)>10 for x in y if x < 10]
[5, 6, 7, 8, 9]
In regular for-loop:
>>> for y in z:
if sum(y)>10:
for x in y:
if x < 10:
print x
5
6
7
8
9
How to frame two for loops in list comprehension python
This should do it:
[entry for tag in tags for entry in entries if tag in entry]
Nested List Comprehension - Double Iteration - Classic CS Problems in Python - Chapter 3 - Word Search
test_list_comp = [locs for values in test.values() for locs in values]
Is equivalent to:
test_list_comp = []
for values in test.values():
for locs in values:
test_list_comp.append(locs)
List comprehensions are evaluated from left to right.
Nested list comprehension not the same as nested for loop
Your list comprehension doesn't do anything as it does not run without i
already been defined outside the list comprehension.
To achieve what you want (and yes, this is counter intuitive ) you need to do this:
[j for i in range(1,5) for j in range(0,i)]
This will yield:
[0, 0, 1, 0, 1, 2, 0, 1, 2, 3]
which is the same order as your nested for loops.
2 List Comprehension in python
When using list comprehension you're building a new list. You don't need to use append.
You don't need to use an interator with list indices and range either.
The inner loop would look like this :
[value*s for value in box]
Here we're building a new list which be the original list with each item multiplied by your s
variable.
Now, we need to create a such list for each box in your current_boxes
.
The outer loop that would do this may be like :
[box for box in current_boxes]
When combined :
all_boxes = [[value*s for value in box] for box in current_boxes]
Related Topics
How to Sort Two Lists (Which Reference Each Other) in the Exact Same Way
How to Check for Valid Email Address
Random.Seed(): What Does It Do
How to Check If a Float Value Is a Whole Number
Non-Alphanumeric List Order from Os.Listdir()
Importerror: Dll Load Failed: %1 Is Not a Valid Win32 Application. But the Dll's Are There
Efficiently Using Multiple Numpy Slices for Random Image Cropping
Download File from Web in Python 3
Elegant Ways to Support Equivalence ("Equality") in Python Classes
Directory-Tree Listing in Python
How to Use Stringio in Python3
Compare Object Instances for Equality by Their Attributes
Can You Monkey Patch Methods on Core Types in Python
The 'Is' Operator Behaves Unexpectedly with Non-Cached Integers