How to make a copy of chained dicts effectively and nicely?

Chris Angelico rosuav at gmail.com
Tue Sep 27 11:26:06 EDT 2016


On Wed, Sep 28, 2016 at 12:54 AM, Jussi Piitulainen
<jussi.piitulainen at helsinki.fi> wrote:
> I wasn't sure if it makes a copy or just returns the dict. But it's
> true: help(dict) says dict(mapping) is a "new dictionary initialized
> from a mapping object's (key, value) pairs".

Yep. With mutable objects, Python's docs are usually pretty clear that
you get a brand-new object every time:

>>> x = [1,2,3,4]
>>> y = list(x)
>>> x == y
True
>>> x is y
False
>>> help(list)
class list(object)
 |  list() -> new empty list
 |  list(iterable) -> new list initialized from iterable's items

With immutables, the docs aren't always explicit, since by definition
it can't matter. Sometimes they are, though:

>>> x = 1,2,3
>>> tuple(x) is x
True
>>> help(tuple)
class tuple(object)
 |  tuple() -> empty tuple
 |  tuple(iterable) -> tuple initialized from iterable's items
 |
 |  If the argument is a tuple, the return value is the same object.

Sometimes things get rather interesting.

>>> help(int)
class int(object)
 |  int(x=0) -> integer
 |  int(x, base=10) -> integer
 |
 |  Convert a number or string to an integer, or return 0 if no arguments
 |  are given.  If x is a number, return x.__int__().  For floating point
 |  numbers, this truncates towards zero.
>>> class SubInt(int):
...  def __int__(self): return self
...
>>> x = SubInt(123)
>>> x.__int__() is x
True
>>> int(x) is x
False
>>> type(int(x))
<class 'int'>

Calling int(x) can return the exact object x, but only if x is an
actual int, not a subclass. If it's a subclass, you get a base integer
with the same value.

In any case, mutables are generally going to be safe: every time you
call the constructor, you get a new object. They won't try to cheat
and return a reference to the same object.

ChrisA



More information about the Python-list mailing list