tags:

views:

181

answers:

3

let's say I have a list

a = [1,2,3]

I'd like to increment every item of that list in place. I want to do something as syntactically easy as

for item in a:
    item += 1

but in that example python uses just the value of item, not its actual reference, so when I'm finished with that loop a still returns [1,2,3] instead of [2,3,4]. I know I could do something like

a = map(lambda x:x+1, a)

but that doesn't really fit into my current code and I'd hate to have to rewrite it :-\

+16  A: 

Here ya go:

# Your for loop should be rewritten as follows:
for index in xrange(len(a)):
    a[index] += 1

Incidentally, item IS a reference to the item in a, but of course you can't assign a new value to an integer. For any mutable type, your code would work just fine:

>>> a = [[1], [2], [3], [4]]
>>> for item in a: item += [1]
>>> a
[[1,1], [2,1], [3,1], [4,1]]
Triptych
Ooooh thanks for clearing that up
spencewah
+7  A: 

Instead of your map-based solution, here's a list-comprehension-based solution

a = [item + 1 for item in a]
Hank Gay
+11  A: 

In python integers (and floats, and strings, and tuples) are immutable so you have the actual object (and not a copy), you just can't change it.

What's happening is that in the line: item += 1 you are creating a new integer (with a value of item + 1) and binding the name item to it.

What you want to do, is change the integer that a[index] points to which is why the line a[index] += 1 works. You're still creating a new integer, but then you're updating the list to point to it.

As a side note:

for index,item  in enumerate(a):
    a[index] = item + 1

... is slightly more idiomatic than the answer posted by Triptych.

Aaron Maenpaa
I started to type enumerate and can't remember why I changed now - haha. I think I wanted to stick to functions any newbie programmer is likely to know, so I went from enumerate to range(len()), then decided I didn't want to encourage the sneaky memory usage of range(), so I changed to xrange(). I'm not always sure when it's a good time to encourage best practice - sometimes _better_ practice is all I think the user is willing to comprehend at the moment.
Triptych
@Triptych: I think it was a good idea to stick to the most elementary functions for a beginner, but I disagree that it's important to introduce xrange. It looks at least as weird as enumerate, and the docs say that xrange's benefit is minimal except in pathological cases. (This has been my experience as well.) And xrange is already spelled range in 3.x.
John Y