切片操作及原理

我首先通过 input() 函数,接收了外部输入字符串,然后通过 list 函数的切片,实现了回文数 代码如下:

s = input()
if s == s[::-1]:
    print('True')
else:
    print('False')
复制代码

结果:adfe False

什么是切片列表?

python中的有序序列都支持切片,不是列表专属的,切片的返回结果类型和切片对象类型一致,返回的是切片对象的子序列,如:对一个列表切片返回一个列表,字符串切片返回字符串。切片生成的子序列元素是源版的拷贝。因此切片是一种浅拷贝。

切片的图示分析

li=["A","B","C","D"]
# 格式:li[start : end : step]    
# start 是切片起点索引,end 是切片终点索引,但切片结果不包括终点索引的值。step 是步长默认是 1。
# [start : end : step) 左开右闭
t = li[0:3]
t1 = li[2:]
t2 = li[1:3]
t3 = li[0:4:2]
print(t)
print(t1)
print(t2)
print(t3)
复制代码

在 step 的符号一定的情况下,start 和 end 可以混合使用正向和反向索引,无论怎样,你都要保证

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

eg:

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

上面的结果都是一样的:t 为 ["A","B"]。

eg2:

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

上面的结果都是一样的:t 为 ["D","C"]。 eg3: t=li[-1:-3] t=li[-1:1] t=li[3:1] t=li[3:-3]

eg3:

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

都切出空列表。

同时,step 的正负决定了切片结果的元素采集的先后。 省略 start 和 end 表示以原列表全部为目标。 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)
print(x)
复制代码

结果:[1, 2, 3] [-1, 2, 3]

列表写操作

在2后面插入若干个元素,应该用列表

x = [1,2,3,4,5]
x[0:2] = [100]
x
#代表在0到2区间插入100
结果:[100, 3, 4, 5]
复制代码
x = [1,2,3,4,5]
x[2:4]=[None]
x
#结果:[1, 2, None, 5]


复制代码

删除切片

>>> del x[2:3]  #删除切片
>>> x
[1, 2, 3, 4, 5]
复制代码

对于切片x[from:to],会进行预处理to=max(from+1,to)

x=[1,2,3,4,5]
x[2:1]=[100]
x
#结果:[1, 2, 100, 3, 4, 5]
复制代码

对于切片del操作,如果from>to,不执行任何操作

x=[1,2,3,4,5]
del x[2:0]
x
#结果:[1, 2, 3, 4, 5]
del x[2:3]
x
#结果:[1, 2, 4, 5]
复制代码

切片原理解析

通过指定下标的方式来获得某一个数据元素,或者通过指定下标范围来获得一组序列的元素,这种访问序列的方式叫做切片。有些地方也把它称之为分片。

先从底层分析切片运算:

list 的切片,内部是调用 getitemsetitemdelitem 和 slice 函数。而 slice 函数又是和 range() 函数相关的。 给切片传递的键是一个特殊的 slice 对象。该对象拥有可描述所请求切片方位的属性

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
复制代码

注:本文根据其它文章练习稍加改动,下面是出处 链接:juejin.im/post/5b5a0c…

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值