Python 列表切片语法的使用没有明显的原因

发布于 2024-07-09 08:36:02 字数 166 浏览 7 评论 0原文

我偶尔会看到 Python 代码中使用的列表切片语法如下:

newList = oldList[:]

当然,这与以下内容相同:

newList = oldList

或者我错过了什么?

I occasionally see the list slice syntax used in Python code like this:

newList = oldList[:]

Surely this is just the same as:

newList = oldList

Or am I missing something?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

给妤﹃绝世温柔 2024-07-16 08:36:02

[:] 浅拷贝列表,复制包含对原始列表成员的引用的列表结构。 这意味着对副本的操作不会影响原始的结构。 但是,如果您对列表成员执行某些操作,两个列表仍会引用它们,因此如果通过原始成员访问成员,则会显示更新。

深层复制也会复制所有列表成员。

下面的代码片段显示了正在运行的浅拷贝。

# ================================================================
# === ShallowCopy.py =============================================
# ================================================================
#
class Foo:
    def __init__(self, data):
        self._data = data

aa = Foo ('aaa')
bb = Foo ('bbb')

# The initial list has two elements containing 'aaa' and 'bbb'
OldList = [aa,bb]
print OldList[0]._data

# The shallow copy makes a new list pointing to the old elements
NewList = OldList[:]
print NewList[0]._data

# Updating one of the elements through the new list sees the
# change reflected when you access that element through the
# old list.
NewList[0]._data = 'xxx'
print OldList[0]._data

# Updating the new list to point to something new is not reflected
# in the old list.
NewList[0] = Foo ('ccc')
print NewList[0]._data
print OldList[0]._data

在 python shell 中运行它会给出以下记录。 我们可以看到
使用旧对象的副本制作列表。 其中一个对象可以有
它的状态通过旧列表的引用进行更新,并且更新可以是
当通过旧列表访问对象时看到。 最后,改变一个
可以看出新列表中的引用没有反映在旧列表中,因为
新列表现在引用不同的对象。

>>> # ================================================================
... # === ShallowCopy.py =============================================
... # ================================================================
... #
... class Foo:
...     def __init__(self, data):
...         self._data = data
...
>>> aa = Foo ('aaa')
>>> bb = Foo ('bbb')
>>>
>>> # The initial list has two elements containing 'aaa' and 'bbb'
... OldList = [aa,bb]
>>> print OldList[0]._data
aaa
>>>
>>> # The shallow copy makes a new list pointing to the old elements
... NewList = OldList[:]
>>> print NewList[0]._data
aaa
>>>
>>> # Updating one of the elements through the new list sees the
... # change reflected when you access that element through the
... # old list.
... NewList[0]._data = 'xxx'
>>> print OldList[0]._data
xxx
>>>
>>> # Updating the new list to point to something new is not reflected
... # in the old list.
... NewList[0] = Foo ('ccc')
>>> print NewList[0]._data
ccc
>>> print OldList[0]._data
xxx

[:] Shallow copies the list, making a copy of the list structure containing references to the original list members. This means that operations on the copy do not affect the structure of the original. However, if you do something to the list members, both lists still refer to them, so the updates will show up if the members are accessed through the original.

A Deep Copy would make copies of all the list members as well.

The code snippet below shows a shallow copy in action.

# ================================================================
# === ShallowCopy.py =============================================
# ================================================================
#
class Foo:
    def __init__(self, data):
        self._data = data

aa = Foo ('aaa')
bb = Foo ('bbb')

# The initial list has two elements containing 'aaa' and 'bbb'
OldList = [aa,bb]
print OldList[0]._data

# The shallow copy makes a new list pointing to the old elements
NewList = OldList[:]
print NewList[0]._data

# Updating one of the elements through the new list sees the
# change reflected when you access that element through the
# old list.
NewList[0]._data = 'xxx'
print OldList[0]._data

# Updating the new list to point to something new is not reflected
# in the old list.
NewList[0] = Foo ('ccc')
print NewList[0]._data
print OldList[0]._data

Running it in a python shell gives the following transcript. We can see the
list being made with copies of the old objects. One of the objects can have
its state updated by reference through the old list, and the updates can be
seen when the object is accessed through the old list. Finally, changing a
reference in the new list can be seen to not reflect in the old list, as the
new list is now referring to a different object.

>>> # ================================================================
... # === ShallowCopy.py =============================================
... # ================================================================
... #
... class Foo:
...     def __init__(self, data):
...         self._data = data
...
>>> aa = Foo ('aaa')
>>> bb = Foo ('bbb')
>>>
>>> # The initial list has two elements containing 'aaa' and 'bbb'
... OldList = [aa,bb]
>>> print OldList[0]._data
aaa
>>>
>>> # The shallow copy makes a new list pointing to the old elements
... NewList = OldList[:]
>>> print NewList[0]._data
aaa
>>>
>>> # Updating one of the elements through the new list sees the
... # change reflected when you access that element through the
... # old list.
... NewList[0]._data = 'xxx'
>>> print OldList[0]._data
xxx
>>>
>>> # Updating the new list to point to something new is not reflected
... # in the old list.
... NewList[0] = Foo ('ccc')
>>> print NewList[0]._data
ccc
>>> print OldList[0]._data
xxx
妄断弥空 2024-07-16 08:36:02

正如 NXC 所说,Python 变量名实际上指向一个对象,而不是内存中的特定位置。

newList = oldList 将创建两个指向同一对象的不同变量,因此,更改 oldList 也会更改 newList

但是,当您执行 newList = oldList[:] 时,它会对列表进行“切片”,并创建一个新列表。 [:] 的默认值为 0 和列表末尾,因此它会复制所有内容。 因此,它会创建一个新列表,其中包含第一个列表中包含的所有数据,但两个列表都可以更改而无需更改另一个列表。

Like NXC said, Python variable names actually point to an object, and not a specific spot in memory.

newList = oldList would create two different variables that point to the same object, therefore, changing oldList would also change newList.

However, when you do newList = oldList[:], it "slices" the list, and creates a new list. The default values for [:] are 0 and the end of the list, so it copies everything. Therefore, it creates a new list with all the data contained in the first one, but both can be altered without changing the other.

起风了 2024-07-16 08:36:02

既然已经回答了,我就简单添加一个简单的演示:

>>> a = [1, 2, 3, 4]
>>> b = a
>>> c = a[:]
>>> b[2] = 10
>>> c[3] = 20
>>> a
[1, 2, 10, 4]
>>> b
[1, 2, 10, 4]
>>> c
[1, 2, 3, 20]

As it has already been answered, I'll simply add a simple demonstration:

>>> a = [1, 2, 3, 4]
>>> b = a
>>> c = a[:]
>>> b[2] = 10
>>> c[3] = 20
>>> a
[1, 2, 10, 4]
>>> b
[1, 2, 10, 4]
>>> c
[1, 2, 3, 20]
笑忘罢 2024-07-16 08:36:02

永远不要认为 Python 中的“a = b”意味着“将 b 复制到 a”。 如果双方都有变量,你就无法真正知道这一点。 相反,可以将其视为“给 b 附加名称 a”。

如果 b 是一个不可变对象(如数字、元组或字符串),那么是的,效果是您得到一个副本。 但这是因为当您处理不可变对象(可能应该被称为只读不可更改WORM)时,您总是 em> 根据定义获取副本。

如果 b 是可变的,您总是需要做一些额外的事情来确保您拥有一个真实的副本总是。 对于列表,就像切片一样简单:a = b[:]。

可变性也是导致以下情况的原因:

def myfunction(mylist=[]): 
    pass

... 并不完全按照您的想法进行。

如果您来自 C 语言背景:“=”的左边始终是一个指针。 所有变量始终都是指针。 如果将变量放入列表中:a = [b, c],则将指向 b 和 c 指向的值的指针放入 a 指向的列表中。 如果随后设置 a[0] = d,则位置 0 中的指针现在指向 d 所指向的任何位置。

另请参阅复制模块:http://docs.python.org/library/copy .html

Never think that 'a = b' in Python means 'copy b to a'. If there are variables on both sides, you can't really know that. Instead, think of it as 'give b the additional name a'.

If b is an immutable object (like a number, tuple or a string), then yes, the effect is that you get a copy. But that's because when you deal with immutables (which maybe should have been called read only, unchangeable or WORM) you always get a copy, by definition.

If b is a mutable, you always have to do something extra to be sure you have a true copy. Always. With lists, it's as simple as a slice: a = b[:].

Mutability is also the reason that this:

def myfunction(mylist=[]): 
    pass

... doesn't quite do what you think it does.

If you're from a C-background: what's left of the '=' is a pointer, always. All variables are pointers, always. If you put variables in a list: a = [b, c], you've put pointers to the values pointed to by b and c in a list pointed to by a. If you then set a[0] = d, the pointer in position 0 is now pointing to whatever d points to.

See also the copy-module: http://docs.python.org/library/copy.html

┈┾☆殇 2024-07-16 08:36:02

浅复制:(将内存块从一个位置复制到另一个位置)

a = ['one','two','three']

b = a[:]

b[1] = 2

print id(a), a #Output: 1077248300 ['one', 'two', 'three']
print id(b), b #Output: 1077248908 ['one', 2, 'three']

深复制:(复制对象引用)

a = ['one','two','three']

b = a

b[1] = 2


print id(a), a #Output: 1077248300 ['one', 2, 'three']
print id(b), b #Output: 1077248300 ['one', 2, 'three']

Shallow Copy: (copies chunks of memory from one location to another)

a = ['one','two','three']

b = a[:]

b[1] = 2

print id(a), a #Output: 1077248300 ['one', 'two', 'three']
print id(b), b #Output: 1077248908 ['one', 2, 'three']

Deep Copy: (Copies object reference)

a = ['one','two','three']

b = a

b[1] = 2


print id(a), a #Output: 1077248300 ['one', 2, 'three']
print id(b), b #Output: 1077248300 ['one', 2, 'three']
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文