tuple()复制参数的元素吗?

时间:2014-02-01 14:00:26

标签: python tuples

在python中,内置函数tuple([iterable])是否创建了一个元组对象并用“iterable”元素的副本填充它,或者它是否创建了一个包含对“iterable”已存在对象的引用的元组“?

4 个答案:

答案 0 :(得分:2)

tuple将迭代序列并复制值。基础序列将存储以实际保留值,但元组表示将替换它。所以是的,转换为元组是实际的工作而不仅仅是另一种类型的嵌套。

转换生成器时可以看到这种情况:

>>> def gen ():
        for i in range(5):
            print(i)
            yield i
>>> g = gen()
>>> g
<generator object gen at 0x00000000030A9B88>
>>> tuple(g)
0
1
2
3
4
(0, 1, 2, 3, 4)

如您所见,生成器立即被迭代,生成值。之后,元组是自包含的,不保留对原始源的引用。作为参考,list()的行为完全相同,但会创建一个列表。

275365指出的行为(在现在删除的答案中)是Python值的标准复制行为。因为Python中的所有内容都是一个对象,所以您基本上只使用引用。因此,在复制引用时,不会复制基础对象。重要的是,每当它们的值发生变化时,将重新创建非可变对象,这些对象不会更新所有先前存在的引用,而只会更新当前正在更改的引用。这就是它的原理:

>>> source = [[1], [2], [3]]
>>> tpl = tuple(source)
>>> tpl
([1], [2], [3])
>>> tpl[0].append(4)
>>> tpl
([1, 4], [2], [3])
>>> source
[[1, 4], [2], [3]]

tpl仍然包含对source列表中原始对象的引用。由于这些是列表,它们是可变的。在任何地方更改可变列表不会使该列表中存在的引用无效,因此更改将同时显示在sourcetpl中。但是,实际的源列表仅存储在source中,tpl没有引用它:

>>> source.append(5)
>>> source
[[1, 4], [2], [3], 5]
>>> tpl
([1, 4], [2], [3])

答案 1 :(得分:1)

是。我认为回答你的两个问题都是“是”。当您从现有的iterable创建一个新元组时,它只会复制每个项目并将其添加到您正在创建的新元组对象中。由于python中的变量实际上是引用对象的名称,因此您创建的新元组实际上将保存对与iterable相同的对象的引用。

我认为question on variable passing会有所帮助。

答案 2 :(得分:1)

tuple([iterables])将使用iterable的引用创建一个元组对象。但是,如果iterable是一个元组,那么它将返回相同的对象,否则它将创建一个从可迭代项初始化的新元组对象。

>>> a = (1,2)
>>> b = tuple(a)
>>> a is b
True

>>> c = [1,2]
>>> d = tuple(c)
>>> c is d
False
>>> c[0] is d[0]
True
>>> c[1] is d[1]
True
>>> type(c), type(d)
(<type 'list'>, <type 'tuple'>)
>>>

答案 3 :(得分:1)

它不会复制或深层复制元素:

a = [{"key": "value"}]
x = tuple(a)
print x #=> ({"key": "value"},)
a[0]["key"] = "fish"
print x #=> ({"key": "fish"},)