带有空列表的切片分配-为什么?

时间:2018-09-22 00:31:25

标签: python slice

我有一个问题。恐怕这对您来说很明显,但是我现在还不太了解。

我刚刚了解了切片分配以及空列表分配如何工作,例如删除项目,例如:

>> L=['a','b','c','d']
>> L[2:3] = []
>> L
['a', 'b', 'd']

但这是我的问题-更加期望此输出是否更合乎逻辑?

['a', 'b', [], 'd']

我知道,如果我的代码如下所示,上述输出将为真:

>> L=['a','b','c','d']
>> L[2:3] = [[]]
>> L

但是为什么用这种方式构造它而不像f.e。:

>> L=['a','b','c','d']
>> L[2:3] = None
>> L

对我来说,它看起来过于复杂,因为我希望在进行切片分配时,我不希望在这种情况下会改变列表的长度,或者我只是想删除切片并启动一个空白同时列出。

编辑:我不知道我是否足够清楚-我不明白为什么-在执行切片分配时-python解释器删除列表中的项目,而不是将此项目更改为空列表。

3 个答案:

答案 0 :(得分:1)

我认为造成混淆的原因是您确实在进行切片,而不是进行索引。观察:

>>> L = ['a','b','c','d']
>>> L[2] = []
>>> L
['a', 'b', [], 'd']

请注意,就2-3的范围而言,L[2:3]L[2]是“相同的”,即为2(因为切片是非包含性的)。但是,切片和索引是两种不同的行为,因为切片可以更改列表的长度,而索引只是修改现有元素。


空列表以这种方式工作的原因是由于切片分配的工作方式。当您分配给切片时,python会解压缩您提供的切片并将其结果存储到索引中。观察:

>>> L = ['a', 'b', 'c', 'd']
>>> L[2:4] = 'e'
>>> L
['a', 'b', 'e']
>>> L = ['a', 'b', 'c', 'd']
>>> L[2:4] = 'efgh'
>>> L
['a', 'b', 'e', 'f', 'g', 'h']

由于Python中字符串的行为,L[2:4] = 'e'L[2:4] = ['e']的行为在python中是相同的:它们可能会迭代并因此解包。

因此,当您放置L[2:4] = []时,它将解压缩[]的所有元素并将它们的内容分配到索引2和3中。当然,由于没有元素,因此它将不分配任何内容。 (注意:与None""不同-实际上什么都没有),因此将其删除。

答案 1 :(得分:0)

切片不会更改长度,分配会更改长度。 切片提取物。 索引选择单个元素。 索引不会更改长度,分配会更改长度。

>>> L = ['a','b','c','d']
>>> L[2:4]   
['c', 'd'] # that's the extraction of a slice.
>>> L[2:4] = []  # that's assignment using a slice and an empty list as operands.  
>>> L
['a', 'b'] 
>>>L[1]
'b'   # that's the selection of an index 
>>>L[1] = 0
>>>L
['a', 0] #that's assignment using an index and integer as operands. 

因此,从字符串列表中提取内容仍应为您提供字符串列表,而不是字符串和空列表-这将是类型的变化。

答案 2 :(得分:0)

当您分配给列表的一部分时,右手参数必须是可迭代的对象。该iterable被解压缩,并且这些值替换原始序列的切片部分中的值。对于步长为1(或负数)的切片,无论切片和可迭代对象的大小是否相同,此方法都有效。

考虑以下示例:

a = [1, 2, 3, 4]
a[1:3] = [5, 6, 7]
print(a) # prints [1, 5, 6, 7, 4]

a = [1, 2, 3, 4]
a[1:3] = [5]
print(a) # prints [1, 5, 4]

您要询问的特定情况只是此行为的一个极端情况。当您为切片分配一个空列表时,切片的值将被删除,并且不会替换它们。任何空的可迭代对象都将以相同的方式工作。

这不是删除项目的标准方法。通常的方法是使用del语句。像a[1:3] = []这样的分片分配与del a[1:3]完全等效,但是后者是首选的,因为它对预期的工作更加明确。