'How to transform loop below in list comprehension?
Is it possible to transform loop below in list comprehension? I know this way is more readable, but anyway just wondering..
new_dict = {"Water Lilly": "flower",
"Swifts": "bird",
"Callery Pear": "tree",
"Swallows": "bird",
"Dahlia": "flower",
"Tulip": "flower",}
for key, value in new_dict.items():
print(key+':')
for val in value:
print("-" + val)
Solution 1:[1]
I think this would work but kinda hard to read :D
x = [(print(key + ":"), [print("-" + val) for val in value]) for key, value in new_dict.items()]
It works like a normal listcomprehension
[do_sth_with_x(x) for x in list]
but your working 2 values
[(do_sth_with_x(x), do_sth_with_y(y)) for x, y in list]
and in the 3th step you add a second list comprehension instead of the do_st_with_y()
there you go there is your listcomp
Solution 2:[2]
It can be done with a one-liner as suggested in this answer. We can agree that the one liner is hard to read. Another issue with it is that we are using side-effects in the comprehension, which is generally considered a bad practice as well.
List comprehensions are expressions; something that evaluates to a value. As opposed to statements, something that is an imperative directive to the interpreter. print(..) statements are, well, statements. Take a look at this SO question to learn about the differences.
Purely as an exercise of converting a nested for loop into list comprehension, we can try and tackle this problem from the inside out.
let's start with a simple example.
for i in list1:
do_something(i)
can be converted to [do_something(i) for i in list1]
but if we have multiple statements, how do we get all of them to execute?
for i in list1:
do_something(i)
do_something_else(i)
we can use a "trick" of python where a tuple is evaluated in order whenever python encounters it.
[(do_something(i), do_something_else(i)) for i in list1]
for key, value in new_dict.items():
do_outer(key)
for val in value:
do_inner(value)
converting the inner loop to List comprehension looks like this
for key, value in new_dict.items():
do_outer(key)
[do_inner(value) for value in value]
next we can try to convert the outer loop
[(inner loop stuff) for key, value in new_dict.items()]
expanding the inner loop stuff
[(do_outer(key), [do_inner(value) for value in value]) for
key, value in new_dict.items()]
We use the tuple trick to club both do_outer and the inner comprehension inside the outer comprehension.
I think we can all agree that the for loop is simpler to read and understand, and looking at the list comprehension, we have no idea what kind of crazy side-effects do_inner and do_outer may cause.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | srj |
