Mysterious for loop in python
Asked Answered
R

5

5

Let exp = [1,2,3,4,5]

If I then execute x in exp, it will give me False. But if I execute :

for x in exp:
    if x==3:
        print('True')

Then execute x in exp, it returns True. What's happening here? I didn't assign anything to x. Did I? I am really confused.

**EDIT:**Sorry if I didn't say this before: x is not defined before.

Answer

Thank you everyone. I understand it now. the elements of exp is assigned to x as exp is iterated over. And x in exp equals True in the last line of code because the last element has been assigned to x.

Retired answered 29/8, 2014 at 17:56 Comment(6)
if you execute x in exp first, it will give you a NameError, not False.Helminthiasis
Nothing is returning anything in this codeMaxma
The answer must be: x was bound to a value that wasn't in exp before. You didn't tell us about the state of x before you ran the for loop however.Paleolith
For those voting to close: there's a pretty clear question here (imho) regarding whether loops do assignments. I don't think this necessarily needs closing.Selie
Agreed with Amber. It's not a perfectly-written question (the red herring in the second sentence definitely isn't helping), but there's a real question here. Unless it's a dup, I don't think there's any reason to close it.Convexity
Mr E, can you please elaborate?Retired
M
18

Seems like you stumbled about in being somewhat overloaded in Python.

  • with x in exp, you are asking "Is x in exp?"
  • with for x in exp: ..., you tell Python "For each element in exp, call it x and do ..."

The latter will assign each of the values in exp to x, one after the other, and execute the body of the loop with that value, so in the first iteration x is assigned 1, in the second 2, and in the last 5. Also, x keeps this value after the loop!

Thus, before the loop, assuming that the variable x is defined but has some other value, x in exp will return False, and after the loop, it returns True, because x is still assigned the last value from exp.

Mcclelland answered 29/8, 2014 at 18:10 Comment(1)
+1, especially with links to the grammar that defines the dual uses of in.Purslane
S
7

for x in ... inherently assigns values to x, because x is the loop variable in a for loop.

Each iteration of the loop assigns a value into x; Python doesn't create a new variable scope for loops.

for x in (1, 2, 3):
    foo(x)

is the equivalent of...

x = 1
foo(x)
x = 2
foo(x)
x = 3
foo(x)
Selie answered 29/8, 2014 at 17:57 Comment(1)
Nice answer. One minor point to make (which the OP won't even understand, but which might be useful to other readers who find this via search): A list comprehension looks a lot like a for loop (because it is one), but it does create a new variable scope (but only in 3.x—in 2.x, generator expressions create new scopes, other comprehensions don't).Convexity
L
2

The syntax is similar, but they mean two different things.

x in exp is a conditional expression; it searches to see if the value of x appears in the list exp. If it's there, the expression evaluates to True, otherwise, False. You can also use not in.

for x in exp introduces a loop where x iterates over the elements of exp. The loop body will be called once for each element, and within the body, x will be set to each element successively.

Loralorain answered 29/8, 2014 at 18:6 Comment(3)
"Conditional expression" in Python means eggs if spam else beans, not eggs in spam. (There probably is an official name for the latter besides "in comparison expression", but it's not coming to me off the top of my head.)Convexity
@Convexity "Membership test."Sizing
Sorry, I meant an expression used in a conditional context, or something. I've always been better at using the stuff than remembering what it's called.Loralorain
U
1

That's how looping works in Python. 'For var in sequence' will assign to var as you iterate through the sequence.

If you were to simply print x for example:

for x in [1, 2, 3, 4, 5]:
    print x

You would see the following:

1
2
3
4
5

Perhaps what you were looking for was just the index of the value? If so, there are a couple of things you could do.

To iterate explicitly with the index, use enumerate(sequence) as such:

for index, x in enumerate(mylist):
    if index == 3:
        do_stuff()

Where the first value (index in this case) will always be the index of the current iteration.

You can also iterate over the length of the object using range(len(sequence)) which is sometimes useful if you're potentially modifying the list as you iterate. Here you're actually creating a separate list using range, with length equal to the len of the list. This will not assign from the list you're targeting -- rather it will assign from the list created by range() -- so you'd have to access it using your for x in... as the index of the list.

for x in range(len(mylist)):
    if mylist[x] == 3:
        things_and_stuff()

As for your second line and point of confusion - 'x in exp' - you will indeed see that x remains assigned after the fact, and so using x in exp will return True because the last assigned value to x is, in fact, in exp.

>>> mylist = [1, 2, 3]
>>> for x in mylist:
...     print x
... 
1
2
3
>>> x
3
>>> x in mylist
True
Ulpian answered 29/8, 2014 at 18:5 Comment(3)
The last one has an even bigger problem than the ones you mentioned. In [1, 2, 3, 1, 2, 3], mylist.index(mylist[3]) isn't 3, it's 0. This is the source of hundreds of Stack Overflow and python-list questions…Convexity
Yes, the last one is awful. I hesitated suggesting it, and maybe I'll just remove it altogether if the OP doesn't realize that for x in sequence is assigning in this way.Ulpian
In fact, yeah deletedUlpian
T
1

When you run your first loop, a variable x is assigned to each value of the list as you iterate over it.

Let's say you start with x=0.

0 is not in [1,2,3,4,5], therefore x in exp = False.

However, when you run the loop, you now have a new x. When the loop is complete, x is initialized to the final element in the list, meaning x=5.

5 is in [1,2,3,4,5], therefore x in exp = True.

Teneshatenesmus answered 29/8, 2014 at 18:26 Comment(1)
Thanks. I now know why x in exp = True.Retired

© 2022 - 2024 — McMap. All rights reserved.