4

This question may be very straightforward and obvious to some people, but for whatever reason I have been unable to find the answer online. I did not find my answer by tinkering with IDLE and trying to understand how it worked. How does a for loop work when multiple items are specified?

a = [1,2,3,4,5]
b = [6,7,8,9,0]
    for item in a and b:
        print 'why does this setup give the list b but nothing from a?'

Followup Questions:

1) What might happen with other operators, such as or and not?

2) Is this proper usage, even? If so, is it messy, unsafe, or frowned upon?

4

6 回答 6

5

So, you have two lists:

>>> a = [1,2,3,4,5]
>>> b = [6,7,8,9,0]

... and you want to iterate over a and b. So what is a and b, exactly?

>>> a and b
[6, 7, 8, 9, 0]

That might look odd, but it's the result of two facts about Python:

  1. Every object is either True-ish or False-ish. For example:

    >>> bool(a)
    True
    >>> bool(b)
    True
    

    In fact, all lists except the empty list [] are True-ish.

  2. Python uses short-circuit evaluation, which means that, for a and b, it:

    • Checks whether a is True-ish or False-ish

    • If a is False-ish, evaluates to a

    • If a is True-ish, evaluates to b

    Following those rules, you should be able to see why a and b evaluates to [6, 7, 8, 9, 0] in your case (and following the same rules for combinations of the actual values True and False will show you that short-circuit evaluation does make sense).

If what you want to actually do is iterate trough the items in a and then those in b, you can just use the + operator to concatenate them:

>>> for item in a + b:
...     print item,
... 
1 2 3 4 5 6 7 8 9 0

As for your followup questions:

What might happen with other operators, such as or and not?

or's rules for short-circuit evaluation are different (you can look them up for yourself or just follow the link above), and in your case a or b evaluates to [1, 2, 3, 4, 5] (in other words, a).

not always returns True for a False-ish value and False for a True-ish value, and since you can't iterate over True or False, you'll get a TypeError.

Is this proper usage, even? If so, is it messy, unsafe, or frowned upon?

Well, there's nothing illegal about it, but as you can see, it doesn't do what you want. There are circumstances where (ab)using short-circuit evaluation to choose an iterable over which to iterate might be helpful, but this isn't one of them.

于 2013-07-12T23:19:54.133 回答
4

As you have discovered, for loops don't work when multiple items are specified! What you're getting is an iteration over a and b. a and b returns something True if both items are true; in this case, it's the rightmost operand, since it knows it's true. The correct way to do this is with itertools.chain:

    for item in itertools.chain(a, b):
        print 'now we get both lists'
于 2013-07-12T23:07:19.943 回答
1

This seem to be a situation where Pythons use of English words ends up being confusing. The statement for item in a and b does not mean "iterate over all items in a and then all items in b" but rater "iterate over all items in the list you get when applying the and operation on the lists a and b".

So what you are doing is the latter. You are anding the two lists a and b and then looping over the result. In the interpreter, anding a and b you get

>>> a = [1,2,3,4,5]
>>> b = [6,7,8,9,0]
>>> a and b
[6, 7, 8, 9, 0]

You can of course do this for any operations, but it is still just applied before the for loop.

To loop over both lists one after the other, replace the and operation with a + to put them together, concatenate them. Like this

>>> a + b
[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
>>> for item in a + b:
...     print item,
... 
1 2 3 4 5 6 7 8 9 0
于 2013-07-12T23:07:12.447 回答
1

The code a and b doesn't join the two lists, it performs the logical and operation. Logical and of two true values, such as lists, evaluates to the value of the second argument. If you use the or operator, it evaluates to the first non-false value. Using not will evaluate to True for a non-true value and False for a true value. Normally, using the value of an and or or as anything other than a Boolean is frowned upon.

There are several ways to accomplish what you're trying to do. The simplest would be to loop over a + b - this gives you a new list. If your lists are large, you might consider using itertools.chain() which will let you loop over all the values without creating a new list object.

于 2013-07-12T23:14:08.397 回答
0

a and b will give b if both a and b are not None or empty or 0. Try typing 1 and 2 in Python shell.

Try:

a = [1,2,3,4,5]
b = [6,7,8,9,0]
for item in a + b:
    print item

You can concatenate lists with the + operator.

于 2013-07-12T23:08:41.907 回答
0

You could also do:

for i in a + b:
    print i

This will join the two lists and allow you to iterate through it.

于 2013-07-12T23:19:58.253 回答