Comprehension on a nested iterables?
--
Music by Eric Matyas
https://www.soundimage.org
Track title: Magic Ocean Looping
--
Chapters
00:00 Question
00:42 Accepted answer (Score 447)
01:12 Answer 2 (Score 349)
02:05 Answer 3 (Score 62)
02:34 Answer 4 (Score 55)
02:52 Thank you
--
Full question
https://stackoverflow.com/questions/1807...
Question links:
[How can I get a flat result from a list comprehension instead of a nested list?]: https://stackoverflow.com/questions/1077...
Answer 1 links:
[image]: https://i.stack.imgur.com/0GoV5.gif
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #list #nested #listcomprehension
#avk47
ACCEPTED ANSWER
Score 489
Here is how you would do this with a nested list comprehension:
[[float(y) for y in x] for x in l]
This would give you a list of lists, similar to what you started with except with floats instead of strings.
If you want one flat list, then you would use
[float(y) for x in l for y in x]
Note the loop order - for x in l comes first in this one.
ANSWER 2
Score 394
Here is how to convert nested for loop to nested list comprehension:
# l a b c d e f
# ↓ ↓ ↓ ↓ ↓ ↓ ↓
l = [ [ [ [ [ [ 1 ] ] ] ] ] ]
new_list = []
for a in l:
for b in a:
for c in b:
for d in c:
for e in d:
for f in e:
out.append(float(f))
new_list = [
float(f)
for a in l
for b in a
for c in b
for d in c
for e in d
for f in e
]
# new_list => [1.0]
For your case, if you want a flat list, it will be something like this.
new_list = [float(y) for x in l for y in x]
Another interesting example with if conditions in the mix:
school_data = [
{
"students": [
{"name": "John", "age": 18, "friends": ["Alice", "Bob"]},
{"name": "Alice", "age": 19, "friends": ["John", "Bob"]},
],
"teacher": "Mr. Smith",
},
{
"students": [
{"name": "Sponge", "age": 20, "friends": ["Bob"]},
],
"teacher": "Mr. tom",
},
]
result = []
for class_dict in school_data:
for student_dict in class_dict["students"]:
if student_dict["name"] == "John" and student_dict["age"] == 18:
for friend_name in student_dict["friends"]:
if friend_name.startswith("A"):
result.append(friend_name)
And here is the listcomp version
result = [
friend_name
for class_dict in school_data
if class_dict["teacher"] == "Mr. Smith"
for student_dict in class_dict["students"]
if student_dict["name"] == "John" and student_dict["age"] == 18
for friend_name in student_dict["friends"]
if friend_name.startswith("A")
]
# result => ['Alice']
ANSWER 3
Score 63
Not sure what your desired output is, but if you're using list comprehension, the order follows the order of nested loops, which you have backwards. So I got the what I think you want with:
[float(y) for x in l for y in x]
The principle is: use the same order you'd use in writing it out as nested for loops.
ANSWER 4
Score 56
>>> l = [['40', '20', '10', '30'], ['20', '20', '20', '20', '20', '30', '20'], ['30', '20', '30', '50', '10', '30', '20', '20', '20'], ['100', '100'], ['100', '100', '100', '100', '100'], ['100', '100', '100', '100']]
>>> new_list = [float(x) for xs in l for x in xs]
>>> new_list
[40.0, 20.0, 10.0, 30.0, 20.0, 20.0, 20.0, 20.0, 20.0, 30.0, 20.0, 30.0, 20.0, 30.0, 50.0, 10.0, 30.0, 20.0, 20.0, 20.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0]