Subbu Dantu
Subbu Dantu

Reputation: 95

How would I change this one line for loop to normal for loop?

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

Answers (6)

Chris
Chris

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

Right leg
Right leg

Reputation: 16720

To flat a nested comprehension out, follow these steps:

  1. First create an empty container: somelist = []
  2. If the comprehension has an if clause, put it right after the for
  3. Then, flat the nested comprehensions out, starting with the innermost

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

Praveen Kumar Verma
Praveen Kumar Verma

Reputation: 7

somelist = []
for c in np.unique(y):
    somelist.append([a for a, b in zip(X, y) if b == c])

Upvotes: 0

jack6e
jack6e

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

Mohamed Ali JAMAOUI
Mohamed Ali JAMAOUI

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

Akshay Apte
Akshay Apte

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

Related Questions