核心知识点:
1.不要写多余的代码:切片的起止索引为0时,有时候使用负值更方便,应该省略;
2.切片不会计较起止索引是否越界;
3.使用切片对列表负值,系统不会考虑范围的长度;
4.更改浅拷贝生产的列表,不会对原列表产生影响,反之,则不同。
Python提供了一种把序列切成小块的写法。这种切片(slice)操作,使得开发者可以轻易的访问由序列中的某些元素所构成的子集。
最简单的用法就是对内置的list、str和bytes进行切割。
切割的基本写法时somelist[start:end],其中start(起始索引)所指的元素覆盖在切割后的范围内,而end(结束索引)所指的元素不包括在切割结果之中。
>>> a = ['a','b','c','d','e','f','g','h','i'] >>> print('First four:',a[:4]) First four: ['a', 'b', 'c', 'd'] >>> print('last four:',a[-4:]) last four: ['f', 'g', 'h', 'i'] >>> print('Middle three:',a[3:-3]) Middle three: ['d', 'e', 'f'] #这里我之所以会多此一举的使用print,我想提醒大家一个概念 #在python解释其中,我们并没有打印,而结果输出了,那是python解释器帮我们执行了print操作。
如果从列表开头获取切片,那就不要在start那里写上0,而是应该把它留空,这样代码会看起来清爽一些。
同样的如果切片一直要取到列表末尾,也要把end留空,因为即便写了也是多余的。
很多时候我们使用负值来表示索引的位置,会显得简单和直白。
切割列表的时候,即便start或end索引越界也不会出现任何问题。利用这一特性,我们可以限定输入序列的最大长度。
>>> print('All:',a[:20]) All: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'] >>> print('All:',a[-20:]) All: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
但是访问单个元素时,下标不能越界,否则就会出现异常。
>>> a[20] Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: list index out of range
对原表进行切割之后,会产生另外一份全新的列表。系统依然维护着指向原列表中各个对象的引用。
在切割后得到的列表上进行修改,不会影响原列表。
>>> b = a[4:] >>> print('Before:',b) Before: ['e', 'f', 'g', 'h', 'i'] >>> b[1] = 99 >>> print('After:',b) After: ['e', 99, 'g', 'h', 'i'] >>> print('No change:',a) No change: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
在赋值时对左侧列表使用切割操作,会把该列表中处在指定范围内的对象替换为新值。
与元祖(tuple)的赋值(如a,b =c[:2])不同(元祖不能改变),此切片的长度无需与新值的个数相等,
位于切片范围之前及之后的那些值都保持不变。列表会根据新值的个数相应的扩张或收缩。
>>> print('Before',a) Before ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'] >>> a[2:7] = [99,22,14] >>> print('After',a) After ['a', 'b', 99, 22, 14, 'h', 'i']
如果对赋值操作右侧的列表使用切片,而把切片的起止索引都留空,那么就会产生一份对原列表的拷贝。
>>> b = a[:] >>> print(a == b) #浅拷贝 True >>> print(a is b) False
关于深浅拷贝的博客:http://www.cnblogs.com/yangmingxianshen/p/7730303.html
如果对赋值操作左侧的列表使用切片,而又没有指定起止索引,那么系统会把右侧的新值赋值一份,
并用这份拷贝来替换掉左侧列表的全部内容,而不会重新分配新的列表。
>>> b = a >>> print('Berofe',a) Berofe ['a', 'b', 99, 22, 14, 'h', 'i'] >>> a[:] = [102,103,104] >>> print('After',a) After [102, 103, 104] >>> print('After',b) After [102, 103, 104] #b还是指向a