1

I'm reading "python cookbook" From it I know that some operations will modified the object assigning to a name. Thus may cause problem. Such as:

a = [1,2,3]
b = a 
b.append(4)
print a, b
[1,2,3,4] [1,2,3,4]

and on this situation, I should:

import copy
b = copy.copy(a)
b.append(5)
print a, b
[1,2,3,4] [1,2,3,4,5]

But if I just assigning a different object to a name, nothing happened, like:

a = 'x'
b = a
a = 0
print a,b
0 x

But a question raised in my head, which are objects that can be modified directly in python, and with what function I can modified them? (So that when I met places which need to use such functions, I know that it's time to use copy)

Zen
  • 4,381
  • 5
  • 29
  • 56
  • Generally, if you don't know whether an object is mutable, you're not going to be mutating it, since you don't know whether it's even possible to do so. Thus, you don't need a copy. If you can look at what you're doing and say, "This line right here mutates the object", then you know enough to need a copy. – user2357112 Apr 03 '14 at 08:07
  • Note that it's not possible to copy all arbitrary objects. For example, iterators usually aren't copyable. Frequently, you can get around this by creating an identical object the same way you got the original, but this isn't always an appropriate solution. – user2357112 Apr 03 '14 at 08:12

4 Answers4

1

From the docs of the copy module:

Assignment statements in Python do not copy objects, they create bindings between a target and an object. For collections that are mutable or contain mutable items, a copy is sometimes needed so one can change one copy without changing the other.

There's an SO question with detailed answers about Mutable vs Immutable types.

Btw, you can use deepcopy instead of just copy when you have "compound objects (objects that contain other objects, like lists or class instances)".

Community
  • 1
  • 1
aneroid
  • 12,983
  • 3
  • 36
  • 66
  • Ah, I see, dict and list are mutable objects. Thanks! – Zen Apr 03 '14 at 08:12
  • No, in that answer, the highest vote answer omitted an important object: set – Zen Apr 03 '14 at 08:29
  • Indeed, most/all of the answers in that thread didn't talk about sets. But they are quite informative. The quick list is provided in [@vz0's answer below](http://stackoverflow.com/a/22831495/1431750). For Sets: They'd behave the same as lists for mutability. – aneroid Apr 03 '14 at 08:35
1

Mutability and immutability is one thing, but another one, which often gets confused, is the effect of an assignment.

If you do

name = value

the name gets (re-)bound to the value.

So, if you do

a = 'x'
b = a
a = 0

it is the same if you do

a = []
b = a
a = {}
  • both of which will assign the first object to b and the second one to a.

No modification takes place here.

If you do b.append(5), you call a method on the object, which leads - in this case - to its modification. An assignment, however, does not lead to modification, but to reassignment.

Usually.

One exception to this are the so-called "augmented assignment operators", such as +=, *= etc. Their behaviour is indeed different for mutable and immutable objects:

  • For an immutable object, a += b is exactly the same as a = a + b: create a new object and leave the old ones intact.
  • For a mutable object, however, a += b mutates a so that it includes b, depending on the semantics. (Or, at least, is allowed or even supposed to do so.)

So from this point of view,

a = ()
bak = a
a += (1, 2)
bak is a # False

and

b = []
bak = b
b += [1, 2]
bak is b # True

.

glglgl
  • 89,107
  • 13
  • 149
  • 217
0

There is no general way to know whether an object is mutable or not, or how to mutate it if it is mutable. You just have to read the documentation to see what is available.

Of the basic builtin types, numbers (ints and floats), strings, and tuples are immutable. Lists, dicts, and sets are mutable. (There is also frozenset which is an immutable version of set.) To see what functions are available for mutating these types, read their documentation. User-defined classes and their instances are also generally mutable. (But classes can set their own mutability rules, making their instances effectively immutable if they want.)

BrenBarn
  • 242,874
  • 37
  • 412
  • 384
0

If my memory serves me well the only objects that are mutable are:

  • lists
  • dicts
  • sets
  • custom objects

Every other type are immutable, including:

  • string
  • numeric types (float, int, complex, etc.)
  • tuples
  • frozensets
vz0
  • 32,345
  • 7
  • 44
  • 77