[Python 2.7.3] What's the difference between these two uses of "for"?

Y

Yves S. Garret

N00b question. But here is the code:

http://bin.cakephp.org/view/709201806

In the first example, the first for-loop is run and then the list is assigned to the tricky variable. But, what
happens in the second example? Does the loop after "in" get run only once or multiple number of times?
 
G

Gary Herron

N00b question. But here is the code:

http://bin.cakephp.org/view/709201806

In the first example, the first for-loop is run and then the list is assigned to the tricky variable. But, what
happens in the second example? Does the loop after "in" get run only once or multiple number of times?

Just once. The sorted fn is called just once, and the resulting list is
iterated through. In your first case, the list is bound to (assigned
to) a name so it is accessible afterwards. In the second case, it is
available for garbage collection immediately after the loop finishes.

Gary Herron
 
A

Andrew Berg

N00b question. But here is the code:

http://bin.cakephp.org/view/709201806

In the first example, the first for-loop is run and then the list is assigned to the tricky variable. But, what
happens in the second example? Does the loop after "in" get run only once or multiple number of times?
In the first example, sorted() returns a list, which is assigned to the
name tricky (Python doesn't have variables - names simply point to
objects in memory), and then the for loop iterates over tricky, which
points to a list. In the second example, the for loop iterates over the
list that sorted() returns. The only difference between the two is that
the list that sorted() returns is assigned to a name in the first example.
 
R

Roy Smith

Yves S. Garret said:
N00b question. But here is the code:

http://bin.cakephp.org/view/709201806

In the first example, the first for-loop is run and then the list is assigned
to the tricky variable. But, what
happens in the second example? Does the loop after "in" get run only once or
multiple number of times?

It's a little hard to answer your question because you're not using the
right terminology. When you say, 'the loop after "in"', I assume you
mean:

[w for w in set(text2) if 'cie' in w or 'cei' in w]

yes? That's not what most people would call "a loop". It's a list
comprehension. For sure, there's an implied looping over the elements
of set(text2) in there, but that's not the way people refer to it.

Anyway, here's what happens. Working from the inside out...

First, set(text2) is evaluated. I assume text2 is something like a list
of strings, or at least iterable which yields strings. This results in
a set object being created. Let's call that set S.

Next, the list comprehension gets evaluated:

[w for w in s if 'cie' in w or 'cei' in w]

This iterates over the the elements of s and forms a list out of those
elements which pass the condition in the 'if' clause. This results in a
list object being created. Let's call that L1

Next, sorted(L1) is evaluated. This returns another list (call it L2).

Finally, we get to:

for word in L2:
print word,

This iterates over all the elements in L2, assigning each one, in turn
to word, and executing the body of the for statement.

Does that answer your question? I'm sure other people will point out
that this is not the most efficient way to do this (your way is not
wrong, it's just not the most efficient way). There's a way to write
this which avoids creating L1. That could be important if there's a
large amount of data involved.

But, make sure you fully understand what's happing in the example you
gave before you move on to the next step.
 
Y

Yves S. Garret

Just once. The sorted fn is called just once, and the resulting list is

iterated through. In your first case, the list is bound to (assigned

to) a name so it is accessible afterwards. In the second case, it is

available for garbage collection immediately after the loop finishes.



Gary Herron

Gotcha, thanks.
 
Y

Yves S. Garret

Just once. The sorted fn is called just once, and the resulting list is

iterated through. In your first case, the list is bound to (assigned

to) a name so it is accessible afterwards. In the second case, it is

available for garbage collection immediately after the loop finishes.



Gary Herron

Gotcha, thanks.
 
Y

Yves S. Garret

N00b question. But here is the code:



In the first example, the first for-loop is run and then the list is assigned
to the tricky variable. But, what
happens in the second example? Does the loop after "in" get run only once or
multiple number of times?



It's a little hard to answer your question because you're not using the

right terminology. When you say, 'the loop after "in"', I assume you

mean:



[w for w in set(text2) if 'cie' in w or 'cei' in w]



yes? That's not what most people would call "a loop". It's a list

comprehension. For sure, there's an implied looping over the elements

of set(text2) in there, but that's not the way people refer to it.



Anyway, here's what happens. Working from the inside out...



First, set(text2) is evaluated. I assume text2 is something like a list

of strings, or at least iterable which yields strings. This results in

a set object being created. Let's call that set S.



Next, the list comprehension gets evaluated:



[w for w in s if 'cie' in w or 'cei' in w]



This iterates over the the elements of s and forms a list out of those

elements which pass the condition in the 'if' clause. This results in a

list object being created. Let's call that L1



Next, sorted(L1) is evaluated. This returns another list (call it L2).



Finally, we get to:



for word in L2:

print word,



This iterates over all the elements in L2, assigning each one, in turn

to word, and executing the body of the for statement.



Does that answer your question? I'm sure other people will point out

that this is not the most efficient way to do this (your way is not

wrong, it's just not the most efficient way). There's a way to write

this which avoids creating L1. That could be important if there's a

large amount of data involved.



But, make sure you fully understand what's happing in the example you

gave before you move on to the next step.

Hi, thanks for the detailed explanation. And yes, you've answered my question.

I'm trying to better understand what's going on behind the scenes and I
appreciate your thorough input. What I don't understand is, how would you
avoid creating L1?
 
R

Roy Smith

Yves S. Garret said:
I'm trying to better understand what's going on behind the scenes and I
appreciate your thorough input. What I don't understand is, how would you
avoid creating L1?

Leave out the square brackets in:

sorted([w for w in set(text2) if 'cie' in w or 'cei' in w])

If you re-write that as:

sorted(w for w in set(text2) if 'cie' in w or 'cei' in w)

Now you've got what's called a generator expression. This iterates over
the same values as the list comprehension would, but it generates them
one at a time, so it doesn't have to store them all somewhere. It
essentially a really neat syntax for writing coroutines.

As usual, Stack Overflow does a pretty good job explaining this:

http://stackoverflow.com/questions/47789/
 
R

Roy Smith

Yves S. Garret said:
I don't get why it's posting what I said twice...

Because you're posting using the Google Groups web interface, right?
Google Groups is just plain busted and double-posts everything (at least
to this group). Not your fault, but something to be aware of. You'd do
better to subscribe to the real email list, or use a traditional NNTP
newsreader.

Google's motto may be "don't be evil", but they get to define what evil
is. Apparently working and playing well with mailing list technology
which has worked just fine for literally decades isn't part of the
definition.
 
S

Steven D'Aprano

I don't get why it's posting what I said twice...

Because you are emailing to the list, and CCing the list.

In your email, you have:

To: (e-mail address removed)
Cc: (e-mail address removed)


Unfortunately, they are the same thing. Or rather, when Google Groups
receives its copy of the email, it then "helpfully" sends another copy to
(e-mail address removed) even though you have already CCed it.

In defence of Google Groups, it's not *quite* as stupid as it appears,
because it's not actually forwarding directly to the same email address.
It is actually forwarding to the newsgroup comp.lang.python, which is an
alias to (e-mail address removed).

Confused? Don't be. It is very simple: there are at least three ways to
post to this group:

1) Email to (e-mail address removed)

2) Post to the news group comp.lang.python on Usenet

3) Email to (e-mail address removed)

There are others as well. Think of them as all aliases to the same
discussion forum. Whichever you choose, choose ONE ONLY. You are using
two, hence there are two copies of your message.

I recommend that you choose 1) or 2) rather than Google Groups, if
possible. There are two problems with Google Groups:

- it is not very smart, and often mangles messages so that every line is
separated by a blank line (although I see you have avoided that, at least
so far!);

- also, we get a lot of spam and junk advertising coming from Google
Groups, and so in self-defence many people here have an automatic filter
that junks anything from Google Groups unread.

If you are unable or unwilling to avoid Google Groups, we will still
answer your questions, but keep in mind that many of the regulars here
will not directly see your posts, but only replies to them.
 
R

Roy Smith

Steven D'Aprano said:
there are at least three ways to
post to this group:

1) Email to (e-mail address removed)

2) Post to the news group comp.lang.python on Usenet

3) Email to (e-mail address removed)

Amongst the ways, there are....
 
D

Dave Angel

I don't get why it's posting what I said twice...

Because you're using googlegroups, and haven't unchecked some poorly
defined default setting. You're posting both to python-list and to
comp.lang.python, each of which is mirrored to the other.

That's one of at least two problems with posting via googlegroups. The
other is the stupid double-spacing of quotes, which is very annoying to
others.


See:
http://wiki.python.org/moin/GoogleGroupsPython
 
A

alex23

Google's motto may be "don't be evil", but they get to define what evil
is.  Apparently working and playing well with mailing list technology
which has worked just fine for literally decades isn't part of the
definition.

Their decision to scrap Reader while ploughing forward with this
godawful new UI for Groups has pushed them into the "evil" basket for
me :(
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top