Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I operate on the actual object, not a copy, in a python for loop?

Tags:

python

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 :-\

like image 741
spencewah Avatar asked Jun 12 '09 18:06

spencewah


People also ask

Does Python for loop make a copy?

The for loop does actually give you the actual object, not copies.

What is the difference between copy and Deepcopy in Python?

A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original. A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.

Which object Cannot be copied in Python?

In Python, Assignment statements do not copy objects, they create bindings between a target and an object. When we use the = operator, It only creates a new variable that shares the reference of the original object.

How do you repeat a specific part of a code in Python?

To loop through a set of code a specified number of times, we can use the range() function, The range() function returns a sequence of numbers, starting from 0 by default, and increments by 1 (by default), and ends at a specified number.


3 Answers

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]]
like image 187
Kenan Banks Avatar answered Sep 22 '22 17:09

Kenan Banks


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.

like image 36
Aaron Maenpaa Avatar answered Sep 18 '22 17:09

Aaron Maenpaa


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

a = [item + 1 for item in a]
like image 27
Hank Gay Avatar answered Sep 21 '22 17:09

Hank Gay