Effective Python(5): 了解切割序列的方法

2019-09-28  本文已影响0人  warmsirius

一、什么是切片?

Python提供了把序列切成小块的写法。这种切片操作,可以实现访问序列中某些元素所构成的子集。

最简单的用法,就是对内置的list、str和bytes进行切割。

注意: 切割操作还可以延伸到实现__getitem__setitem这两个特殊方法的Python类上。

二、切片的使用

1. 基本写法

somelist[start:end]

举例:

a = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
print('First four:', a[:4])
print('Last four', a[-4:])
print('Middle two', a[3:-3]

# 结果
First four: ['a', 'b', 'c', 'd']
Last four: ['e', 'f', 'g', 'h']
Middle two: ['d', 'e']

原则1:如果要从列表开头获取切片,那就不要在start那里写上0,而应该留空

assert a[:5] == a[0:5]

原则2:如果切片要一直取到列表末尾,那就应该把end留空

assert a[5:] == a[5: len(a)]

原则3:指定切片起止索引时,若要从列表尾部向前算,则使用负值表示相关偏移量

a[2: -1]

注意1: 值小的位置元素永远能取到,值大的位置元素永远取不到,正负一样道理。
注意2: 如果使用负变量作为start索引来切割列表,如果start=0时,表达式somelist[-0:]则成了原列表的一份拷贝。

原则4:切割列表时,即便startend索引越界也不会出问题

a[:20]
a[-20:]

注意: 访问列表中的单个元素时,下标不能越界,否则会导致异常

三、技术细节

1. 对原列表进行切割之后,会产生另外一份全新的列表。

系统依然维护这指向原列表中各个对象的引用。在切割后得到的新列表上进行修改,不会影响原列表。

2. 赋值时对左侧列表进行切割操作,会把该列表中处在指定范围内的对象替换为新值

  • 与元组(tuple)的赋值(如a, b = c[:2])不同,列表切片赋值的长度无需新值个数相等。
  • 位于切片范围之前及之后的那些值都保留不变。列表会根据新值的个数相应地扩张或收缩。

3. 如果对赋值操作右侧的列表使用切片,而把切片的起止索引都留空,那就会产生一份原列表的拷贝

b = a[:]
assert b == a and b is not a

4. 如果对赋值操作左侧的列表使用切片,而又没有指定起止索引,那么系统会把右侧的新值复制一份,并用这份拷贝来替换左侧列表的全部内容,而不会重新分配新的列表。

b = [1, 2, 3]
b = a
a[:] = [101, 102, 103]
assert b is a

四、要点

上一篇下一篇

猜你喜欢

热点阅读