| Hello,
|          was just trying to do something and tried the following code:
| 
| list = ["1", "test", "1.5"]
| 
| for x in list:
|     print list.pop(x)
| 
| I get the following error:
| 
| print list.pop(x)
| TypeError: an integer is required
| 
| Does this mean i can't use a for loop to pop things from a list? or is
| there another way to do it?

In the interactive window you can request help to see if that gives you a clue 
as to what might be going wrong:

###
>>> help(list.pop)
Help on method_descriptor:

pop(...)
    L.pop([index]) -> item -- remove and return item at index (default last)

###

So you must supply an index (which is an integer) defining which item you want 
to remove (or else supply no argument and automatically get the default which 
is the last item). You should not tell pop *what* you want to pop--which is 
what you did with the "x"--you should tell it which item *number* you want to 
pop--which you did in your next attempt.

| 
| I also tried the following:
| 
| list = ["1", "test", "1.5"]
| 
| for x in list:
|     print list.pop(0)
| 
| which worked but returned the following:
| 
| 1
| test
| 
| Why did it not return the last value in the list?
| 

The "for x in list" is shorthand for the following equivalent syntax:

i=0
while i <len(list):
    ...
    #your code
    ...
    i=i+1

So here's what's happening:

first pass, i=0, list length is 3; enter loop and pop off the '1'
second pass, i=1, list length is 2; enter loop and pop off the 'test'
third pass, i=2, list length is 1; the loop is not entered

The "i" here is something that the "for x in l" is keeping track of. Since it 
is 2 on your attempted 3rd pass and this is greater than the length of the list 
at that point, you never get inside the loop and you don't see the last item 
popped off. (See below for a little tangent on the "i" and "l" that are being 
used.)

If you really want to pop off all 3 elements, then you could reference a list 
that doesn't change as you pop off the elements that has the same length as 
your list:

for x in range(len(list)):
    print list.pop(0)

NOTE: a list is created by range *once* and is not created each time the loop 
is run, so for your list, range(len(list)) => range(3) => [0, 1, 2]

Another approach you could use is to keep popping off elements until the list 
is consummed:

while list:
    print list.pop(0)

-----------------
OK, here's the aside--you might want to skip this for now.
-----------------

If we reshuffle the list while we are walking through it, we can keep printing 
the same thing (not that we would really want to, but you get the idea that 
some internal index is advancing you through the list)
###
>>> for x in l:
...  print x,l
...  l[:]=l[-1:]+l[0:-1] #rotate the list to the right
...  
1 ['1', 'test', '1.5']
1 ['1.5', '1', 'test']
1 ['test', '1.5', '1']
###

But here is the first attempt that I made to do this and it gave a different 
result:
###
>>> for x in l:
...  print x,l
...  l=l[-1:]+l[0:-1]
...  
1 ['1', 'test', '1.5']
test ['1.5', '1', 'test']
1.5 ['test', '1.5', '1']
###

So it appears that not only does the "for x in l" keep track of an index, it 
also keeps track of the original 'l' and allows me to point an 'l' in the loop 
to something separate from the one it is keeping track of. So it seems the "for 
x in l" is doing something like:

i=0
tempList = list
while i<len(tempList):
    ...
    i=i+1

In the attempt at redefining 'l' that I showed first above, I was not making 
'l' point at something new, I was modifying elements of the thing that 'l' 
pointed to which was also the thing that 'tempList' was pointing to so I always 
saw the '1' printed since the list rotation caused this alway to be the next 
thing. In the second example, I was creating something different from tempList 
and so I wasn't seeing those elements being printed. This concept of 'pointing' 
can be shown with the following:

###
>>> l=range(3)
>>> a=l     # 'a' is pointing at what 'l' is pointing at
>>> l[0]=42 # I make a change to the thing that 'l' points to
>>> print a
[42, 1, 2]
>>> print l
[42, 1, 2]
>>> 
###

Since a and l point at the same thing, they both show the change. But compare 
that to this:

###
>>> l=range(3)
>>> a=l  # 'a' and 'l' point to the same thing
>>> l=42 # here I make 'l' point to something else
>>> print a
[0, 1, 2]
>>> print l
42
###

This perplexing issue is something that bites most of us at some time. I hope I 
haven't made it more perplexing ;-) If you have more questions, ask. 

/c
_______________________________________________
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor

Reply via email to