2016-01-29 30 views
3

我在学习Python,来自C#/ Java背景,并且正在玩弄列表行为。我已经阅读了一些文档,但我不明白如何以及为什么使用索引大于长度为1的分片可以附加项目。在Python中追加列表的说明和首选方法

ls = ["a", "b", "c", "d"] 
n = len(ls) # n = 4 

letter = ls[4] # index out of range (list indexes are 0 - 3) 

# the following all do the same thing 

ls += ["echo"] 
ls.append("foxtrot") 
ls[len(ls):] = ["golf"] # equivalent to ls[len(ls): len(ls)] 

print(ls) 

尽管对我来说这似乎很奇怪,但我知道切片如何修改它们操作的列表。我没有得到的是为什么list[len(list)]导致预期的越界误差,但list[len(list):]没有。我知道切片与索引有根本的区别,而不是当切片以列表值之外的索引开始时在内部发生的情况。

为什么我可以从一个不存在的元素(len(list))开始的列表中返回一个切片?为什么这让我扩大名单?

此外,上述前三种附加项目的方法中,从约定或性能角度来看,哪一项更受欢迎?它们中的任何一个都存在性能劣势?

+0

我无法解释当你影响列表拼接时发生了什么(我甚至不知道为什么这是允许的)。首选的形式在python中是最常用的,它可以是'ls + = [“alpha”]或'ls.append(“tango”)'。从性能角度来看,这取决于你的python解释器。 – DainDwarf

+0

请缩小你的问题;目前尚不清楚它是否是http://stackoverflow.com/q/9490058/3001761或http://stackoverflow.com/q/10623302/3001761或其他内容的重复。你也可以把它看作是改进它的一部分,已经有很多信息了。 – jonrsharpe

+0

注意'ls + ='需要'ls'在本地范围内(或者在函数中给定'global'声明),因为它执行的是分配,但是'ls.append'可以在全局变量上工作,因为它仅仅是一个方法调用一个现有的可变对象,而不是一个赋值。 “ –

回答

1

虽然a.append(x)a[len(a):] = [x]做同样的事情,第一个是更清晰,应该几乎总是被使用。切片更换可能有一个地方,但你不应该找理由去做。如果情况需要的话,应该明确何时做到这一点。

从索引返回列表元素开始,切片返回列表的“子列表”。虽然特定元素存在或不存在,但从数学角度来看,每个列表都有空列表作为任何两个相邻位置之间的“子列表”。考虑

>>> a = [1, 2, 3] 
>>> a[2:2] 
[] 

现在考虑以下顺序。在每一步中,我们增加切片

>>> a[0:] # A copy of the list 
[1, 2, 3] 
>>> a[1:] 
[2, 3] 
>>> a[2:] 
[3] 

每一次我们这样做的起始索引,我们从列表中所产生的片的开头删除一个多种元素。那么当起始索引最终等于最终索引(这隐含地是列表的长度)时会发生什么?

>>> a[3:] 
[] 

你得到一个空列表,这与以下身份

a + [] = a 
a[:k] + a[k:] = a 

是一致的(第一个是第二个地方k >= len(a)。的特殊情况,现在

,一旦我们看到为什么切片存在是有意义的,用另一个列表替换切片意味着什么?换句话说,如果我们用[1, 2, 3]替换列表[4]的末尾的空列表,我们会得到什么样的列表?您得到[1, 2, 3, 4],这符合

[1, 2, 3] + [4] = [1, 2, 3, 4] 

考虑另一个序列,这次涉及片替换。

>>> a = [1,2,3]; a[0:] = ['a']; a 
['a'] 
>>> a = [1,2,3]; a[1:] = ['a']; a 
[1, 'a'] 
>>> a = [1,2,3]; a[2:] = ['a']; a 
[1, 2, 'a'] 
>>> a = [1,2,3]; a[3:] = ['a']; a 
[1, 2, 3, 'a'] 

查看切片替换的另一种方法是将其视为将列表附加到原始子列表中。当该子列表本身是列表时,则等于追加到原始列表。

+0

很好的解释。思考片段之间发生的切片(或者元素和列表的末尾)使得操作对我来说是可理解的。 – BrianHVB

0

为什么我可以从一个不存在的元素开始列表返回分得一杯羹?

我无法确定,但我的猜测是,这是因为可以返回一个合理的值(没有元素指的是,所以返回一个空列表)。

为什么这可以让我扩大名单?

您的切片选择列表的最后0个元素。然后您将这些元素替换为另一个列表的元素。

而且,用于附加的项,其中之一是优选的

使用.append()如果要添加单个元素的前三个以上的方法,如果你有内的另一个列表中的元素.extend()

我对性能不太确定,但我的猜测是那些优化非常好。

+0

”您的切片选择列表中最后的0个元素,然后将这些元素替换为另一个列表的元素。“我想这是我无法包裹头部的部分。选择“无”并将其替换为“某物”。我明白你可能会选择最后一个元素,并用[last_elem,new_elem]替换它,但那不是发生了什么。太可能是元物理。奇怪的行为,但没有办法解决。我只是不喜欢不知道它是如何工作的。 – BrianHVB