# 贝斯狸的 Python 之旅 -- 深入切片操作及原理

```s = input()
if s == s[::-1]:
print("True")
else:
print("False")

>>> abcba
True```

```li=["A","B","C","D"]
# 格式：li[start : end : step]
# start 是切片起点索引，end 是切片终点索引，但切片结果不包括终点索引的值。step 是步长默认是 1。
# [start : end : step) 左开右闭
t=li[0:3]        ["A","B","C"]       #起点的0索引可以省略，t=li[:3]
t=li[2: ]        ["C","D"]           #省略end，则切到末尾
t=li[1:3]        ["B","C"]
t=li[0:4:2]      ["A","C"]            #从li[0]到li[3],设定步长为2。          ```

start 和 end 之间有和 step 方向一致元素间隔，否则会切出空列表。

#### Case 1

t=li[0:2] t=li[0:-2] t=li[-4:-2] t=li[-4:2]

#### Case 2

t=li[-1:-3:-1] t=li[-1:1:-1] t=li[3:1:-1] t=li[3:-3:-1]

#### Case 3

t=li[-1:-3] t=li[-1:1] t=li[3:1] t=li[3:-3]

t=li[::-1] t--->["C","B","A"] #反向切，切出全部。

t=li[:] t--->["A","B","C","D"] #正向切全部。

```x=[1,2,3]
y=x[:]
x[0]=-1
print(y) #输出[1,2,3]```

#### 切片写操作

```#case 1
>>> x=[1,2,3,4,5]
>>> x[2:0]=100  #在2后面插入若干个元素，应该用列表
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only assign an iterable
>>> x[2:0]=[100]
>>> x
[1, 2, 100, 3, 4, 5]

#case 2
>>> x[2:4]=None
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only assign an iterable
>>> x[2:4]=[None]
>>> x
[1, 2, None, 5]```

```>>> del x[2:3]  #删除切片
>>> x
[1, 2, 3, 4, 5]```

```>>> x=[1,2,3,4,5]
>>> x[2:1]=[100] #对于切片x[from:to]，会进行预处理to=max(from+1,to)
>>> x
[1, 2, 100, 3, 4, 5]```

```>>> del x[2:0]
>>> x
[1, 2, 100, 3, 4, 5]
>>> del x[2:1]
>>> x
[1, 2, 100, 3, 4, 5]
>>> del x[2:3]
>>> x
[1, 2, 3, 4, 5]```

#### 切片原理解析

list 的切片，内部是调用 `__getitem__``__setitem__``__delitem__` 和 slice 函数。而 slice 函数又是和 range() 函数相关的。

```a = [1,2,3,4,5,6]
x = a [ 1 : 5 ]                # x = a.__getitem__(slice( 1, 5, None))
a [ 1 : 3 ] = [10, 11, 12 ]    # a.__setitem__(slice(1, 3, None), [ 10, 11, 12 ])
del a [ 1 : 4 ]                # a.__delitem__(slice(1, 4, None))```

```def between(beg, end, mid):
# 判断mid是否位于begin和end之间
return end > mid >= beg or end < mid <= beg

def get_slice(a, beg, end, delta=1):
# 数组切片get方式
if delta == 0:
raise ValueError("slice step cannot be 0")
# 将负数下标转化一下
if beg < 0:
beg += len(a)
if end < 0:
end += len(a)
# 如果转化完成之后依然不在合法范围内，则返回空列表
if beg < 0 and end < 0 or beg >= len(a) and end >= len(a):
return []
# 如果方向不同，则返回空列表
if (end - beg) * delta <= 0:
return []
# 将越界的部分进行裁剪
beg = max(0, min(beg, len(a) - 1))
end = max(-1, min(end, len(a)))
ans = []
i = beg
while between(beg, end, i):
ans.append(a[i])
i += delta
return ans

def set_slice(a, li, beg, end, delta=1):
if delta == 0:
raise ValueError("slice step cannot be 0")
if delta == 1:
# 如果delta==1，那么li的长度可以随意
if beg < 0:
beg += len(a)
if end < 0:
end += len(a)
beg = max(0, min(beg, len(a) - 1))
end = max(-1, min(end, len(a)))
for i in range(beg, end):
del a[beg]
for i in reversed(li):
a.insert(beg, i)
else:
# delta!=1,相当于替换
if len(get_slice(a, beg, end, delta)) != len(li):
raise ValueError("array don't match")
if len(li) == 0:
return
if beg < 0:
beg += len(a)
if end < 0:
end += len(a)
beg = max(0, min(beg, len(a) - 1))
# 用li中的全部元素逐一替换
for ind, value in enumerate(li):
a[ind * delta + beg] = value```

1、本次贝斯狸的 Python 学习之旅是一次尝试，想让程序员学习生活变得更加有乐趣，也算满足了我的愿望，重拾 PhotoShop，后面还会更新更多有趣可爱的对话，轻松实现学习生活两不误。 2、学习知识是一个循序渐进的过程，正如小狸一样，学会了使用，但是却没有深入，小组长随机抽查便中了招，所以我们要时刻保持好奇心，凡事多问个为什么？这样才能进步。

0 条评论

• ### 前端每日实战：112# 视频演示如何用纯 CSS 创作切换背景的按钮悬停效果

https://github.com/comehope/front-end-daily-challenges

• ### 【C++简明教程】C++简介与环境配置

过去一两年 Python 可谓火爆，『人生苦短，我用 Python』成为各个 Pythoner 使用它的借口。毫无疑问 Python 在人工智能领域对比其他语言...

• ### 揭秘知乎大V [Python数据分析]

知乎，可以说是国内目前最大的问答类社区。与微博、贴吧等产品不同，知乎上面的内容更多是用户针对特定的问题分享知识、经验和见解。咱们编程教室就有不少读者是从知乎上了...

• ### 视野前端（二）V8引擎是如何工作的

许多同学在阅读了基础进阶系列文章之后，对JS代码的执行顺序理解得更清晰了。可也有不少好学的大佬在此基础上进一步思考，JS引擎到底是如何工作的？什么时候解析？什...

• ### iostat命令使用

天刚上线了一台server，观察了一下，发现io比较高，想到了iostat命令，观察了一下（每隔一秒打印一次），发现有一个守护进程每隔几秒就写一次IO，再top...