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.

6
  • 3
    if you execute x in exp first, it will give you a NameError, not False. Commented Aug 29, 2014 at 17:58
  • Nothing is returning anything in this code Commented Aug 29, 2014 at 17:58
  • 2
    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. Commented Aug 29, 2014 at 17:59
  • 4
    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. Commented Aug 29, 2014 at 18:01
  • 1
    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. Commented Aug 29, 2014 at 18:04

5 Answers 5

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.

Sign up to request clarification or add additional context in comments.

1 Comment

+1, especially with links to the grammar that defines the dual uses of in.
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)

1 Comment

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).
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.

3 Comments

"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.)
@abarnert "Membership test."
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.
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

3 Comments

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…
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.
In fact, yeah deleted
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.

1 Comment

Thanks. I now know why x in exp = True.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.