使用 [:] 列出分配

发布于 2024-12-08 06:34:57 字数 272 浏览 0 评论 0原文

在赋值

lst  = range(100)

lst[:] = range(100)

之前,lst 变量已分配给列表:

lst = [1, 2, 3]
lst = range(100)

lst = [1, 2, 3]
lst[:] = range(100)

What's the difference between

lst  = range(100)

and

lst[:] = range(100)

Before that assignment the lst variable was already assigned to a list:

lst = [1, 2, 3]
lst = range(100)

or

lst = [1, 2, 3]
lst[:] = range(100)

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

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

发布评论

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

评论(6

素食主义者 2024-12-15 06:34:57

当您这样做时,

lst = anything

您将 name lst 指向一个对象。它不会以任何方式更改用于指向的旧对象 lst,尽管如果没有其他东西指向该对象,其引用计数将降至零,并且它将得到已删除。

当你这样做时,

lst[:] = whatever

你会迭代whatever,创建一个中间元组,并将元组的每个项目分配给已经存在的 lst 对象。这意味着如果多个名称指向同一个对象,当您引用任何名称时,您将看到反映的更改,就像您使用 appendextend 或任何其他就地操作。

差异的一个例子:

>>> lst = range(1, 4)
>>> id(lst)
74339392
>>> lst = [1, 2, 3]
>>> id(lst)  # different; you pointed lst at a new object
73087936
>>> lst[:] = range(1, 4)
>>> id(lst)  # the same, you iterated over the list returned by range
73087936
>>> lst = xrange(1, 4)
>>> lst
xrange(1, 4)   # not a list, an xrange object
>>> id(lst)   # and different
73955976
>>> lst = [1, 2, 3]
>>> id(lst)    # again different
73105320
>>> lst[:] = xrange(1, 4) # this gets read temporarily into a tuple
>>> id(lst)   # the same, because you iterated over the xrange
73105320
>>> lst    # and still a list
[1, 2, 3]

就速度而言,切片分配速度较慢。有关内存使用情况的更多信息,请参阅 Python 切片分配内存使用情况

When you do

lst = anything

You're pointing the name lst at an object. It doesn't change the old object lst used to point to in any way, though if nothing else pointed to that object its reference count will drop to zero and it will get deleted.

When you do

lst[:] = whatever

You're iterating over whatever, creating an intermediate tuple, and assigning each item of the tuple to an index in the already existing lst object. That means if multiple names point to the same object, you will see the change reflected when you reference any of the names, just as if you use append or extend or any of the other in-place operations.

An example of the difference:

>>> lst = range(1, 4)
>>> id(lst)
74339392
>>> lst = [1, 2, 3]
>>> id(lst)  # different; you pointed lst at a new object
73087936
>>> lst[:] = range(1, 4)
>>> id(lst)  # the same, you iterated over the list returned by range
73087936
>>> lst = xrange(1, 4)
>>> lst
xrange(1, 4)   # not a list, an xrange object
>>> id(lst)   # and different
73955976
>>> lst = [1, 2, 3]
>>> id(lst)    # again different
73105320
>>> lst[:] = xrange(1, 4) # this gets read temporarily into a tuple
>>> id(lst)   # the same, because you iterated over the xrange
73105320
>>> lst    # and still a list
[1, 2, 3]

When it comes to speed, slice assignment is slower. See Python Slice Assignment Memory Usage for more information about its memory usage.

匿名的好友 2024-12-15 06:34:57

第一个重新定义内置名称 list 以指向某个列表。

第二个失败,并显示 TypeError: 'type' object does not support item assignment

The first one redefines the built-in name list to point to some list.

The second fails with TypeError: 'type' object does not support item assignment.

撩人痒 2024-12-15 06:34:57

仅当已经存在名为 list 且允许切片分配的对象时,list[:] 才会起作用。

另外,您不应该命名变量 list,因为有一个名为 list 的内置变量,它本身就是 list 类型。

list[:] will only work if there is already an object named list that allows slice assignment.

Also, you shouldn't name variables list because there is a built-in named list which is the list type itself.

知你几分 2024-12-15 06:34:57

list[:] 指定列表内的范围,在本例中,它定义列表的完整范围,即整个列表并更改它们。另一方面,list=range(100) 会擦除 list 的原始内容并设置新内容。

但请尝试以下操作:

a=[1,2,3,4]

a[0:2]=[5,6]

a # prints [5,6,3,4]

您看,我们通过赋值更改了前两个元素。这意味着,使用此表示法,您可以一次更改列表中的多个元素。

list[:] specifies a range within the list, in this case it defines the complete range of the list, i.e. the whole list and changes them. list=range(100), on the other hand, kind of wipes out the original contents of list and sets the new contents.

But try the following:

a=[1,2,3,4]

a[0:2]=[5,6]

a # prints [5,6,3,4]

You see, we changed the first two elements with the assignment. This means, using this notation, you can change several elements in the list once.

半城柳色半声笛 2024-12-15 06:34:57

[:] 对于制作列表的深层副本也很有用。

def x(l):
    f=l[:]
    g=l
    l.append(8)
    print "l", l
    print "g", g
    print "f", f

l = range(3)

print l
 #[0, 1, 2]

x(l)
 #l [0, 1, 2, 8]
 #g [0, 1, 2, 8]
 #f [0, 1, 2]

print l
#[0, 1, 2, 8]

对 l 的修改反映在 g 中(因为,两者都指向同一个列表,事实上,g 和 l 都只是 python 中的名称),而不是反映在 f 中(因为,它是 l 的副本)

但是,在你的情况下,它没有任何区别。 (不过,我没有资格评论这两种方法的任何内存使用情况。)

编辑

h = range(3)
id(h) #141312204 
h[:]=range(3)
id(h) #141312204 
h=range(3)
id(h) #141312588 

list[:] = range(100) 更新列表
list = range(100) 创建新列表。

@agf:感谢您指出我的错误

[:] is also useful to make a deep copy of the list.

def x(l):
    f=l[:]
    g=l
    l.append(8)
    print "l", l
    print "g", g
    print "f", f

l = range(3)

print l
 #[0, 1, 2]

x(l)
 #l [0, 1, 2, 8]
 #g [0, 1, 2, 8]
 #f [0, 1, 2]

print l
#[0, 1, 2, 8]

Modification to l is get reflected in g (because, both point to same list, in fact, both g and l are just names in python), not in f(because, it's a copy of l)

But, in your case, It doesn't make any difference. (Though, I'm not eligible to comment on any memory usage of both methods.)

Edit

h = range(3)
id(h) #141312204 
h[:]=range(3)
id(h) #141312204 
h=range(3)
id(h) #141312588 

list[:] = range(100) updates the list
list = range(100) creates new list.

@agf: thanks for pointing my error

莫相离 2024-12-15 06:34:57
list[:] = range(100)

不适用于未初始化的变量,因为它正在修改它。 [:] 指定整个列表/元组。

list[:] = range(100)

won't work on uninitialized variable, as it is modifying it. The [:] specifies the whole list/touple.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文