Reputation: 95
This is a general question that I was not to able to understand.
If I have this:
somelist = [[a for a, b in zip(X, y) if b == c] for c in np.unique(y)]
How can I write this as normal multiline for loop? I never seem to get it right.
EDIT: So far I've tried this:
somelist = []
for c in np.unique(y):
for x, t in zip(X, y):
if t == c:
separated.append(x)
But I wasn't sure if this was right because I wasn't getting an expected result in some other part of my code.
Upvotes: 3
Views: 629
Reputation: 22953
Your were very close. The problem with your approach is that you forgot an important point: The result of the list comprehension will be a list of lists. Thus, the values computed in the inner loop, need to be held in a temporary list that will be append to the "main" list somelist
to create a list of lists:
somelist = []
for c in np.unique(y):
# create a temporary list that will holds the values computed in the
# inner loop.
sublist = []
for x, t in zip(X, y):
if t == c:
sublist.append(x)
# after the list has been computed, add the temporary list to the main
# list `somelist`. That way, a list of lists is created.
somelist.append(sublist)
The general rule of thumb when converting a list comprehension to a vanilla for loop is that for each level of nesting, you'll need another nested for
loop and another temporary list to hold the values computed in the nested loop.
As a caveat, once you start getting past 2-3 leves of nesting in your comprehension, you should seriously consider coveting it to a normal for loop. Whatever efficacy you're gaining, it offset my the unreliability of the nested list comprehension. Remember, "97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%".
Upvotes: 1
Reputation: 16720
To flat a nested comprehension out, follow these steps:
somelist = []
if
clause, put it right after the for
The inner comprehension is:
row = []
for a, b in zip(X, y):
if b == c:
row.append(a)
Then, somelist is nothing more than [row for c in np.unique(y)]
, where row
depends on several factors.
This one is equivalent to:
somelist = []
for c in np.unique(y):
somelist.append(row)
So the complete version is:
somelist = []
for c in np.unique(y):
row = []
for a, b in zip(X, y):
if b == c:
row.append(a)
c.append(row)
Upvotes: 2
Reputation: 7
somelist = []
for c in np.unique(y):
somelist.append([a for a, b in zip(X, y) if b == c])
Upvotes: 0
Reputation: 1522
After offering the obvious caveat that, for performance and Pythonic reasons, you should not expand your list comprehension into a multi-line loop, you would write it from the outside in:
somelist = []
for c in np.unique(y):
inner_list = []
for a, b in zip(X, y):
if b == c:
inner_list.append(a)
somelist.append(inner_list)
And now you see the beauty of list comprehensions.
Upvotes: 0
Reputation: 14689
This how it looks like using "normal" for-loop (a.ka. without using list comprehension):
somelist = []
for c in np.unique(y)
l = []
for a, b in zip(X, y):
if b == c:
l.append(a)
somelist.append(l)
Upvotes: 1
Reputation: 1653
Let me know if this works: evaluate the outer list comprehension first for the outer loop. then evaluate the inner list comprehension.
somelist=[]
for c in np.unique(y):
ans=[]
for a,b in zip(X,y):
if b==c:
ans.append(a)
somelist.append(ans)
Upvotes: 3