我有一个问题。恐怕这对您来说很明显,但是我现在还不太了解。
我刚刚了解了切片分配以及空列表分配如何工作,例如删除项目,例如:
>> 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解释器删除列表中的项目,而不是将此项目更改为空列表。
答案 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]
完全等效,但是后者是首选的,因为它对预期的工作更加明确。