Python 基础第五话:python3 实现自定义切片类为左闭右闭

一、Python 切片的一些用法

alist = [3,4,5,6,7,9,11,13,15,17]
print(alist[::]) # 返回包含原列表中所有元素的新列表
print(alist[::-1]) # 返回原列表的逆序排列
print(alist[::2]) # 返回原列表的偶数位数据
print(alist[1::2]) # 获取奇数位置的数据
print(alist[3:6]) # 指定切片的开始和结束位置
print(alist[0:100]) # 切片位置大于列表长度时,从列表尾部截断
print(alist[100:]) # 切片开始位置大于列表长度时,返回空列表
alist[len(alist):]=[9] # 在列表尾部增加元素
print(alist)
alist[:0] = [1,2] # 前面的0省略了,相当于是alist[0:0] = [1,2]
print(alist)      # 在列表的头部增加元素
alist[3:3] =[4] # 在列表中间插入元素
print(alist)
alist[:3] = [1,2] # 相当于是alist[0:3] = [1,2] 替换列表元素
alist[3:] = [4,5,6] # 替换元素,结果按照两边的最短元素来决定.
print(alist)
alist[:3] = []  # 删除列表中前三个元素
del alist[:3] # 切片元素连续
del alist[::2] # 隔一个删除一个,切片元素不连续

二、自定义实现一个可切片的序列类

        Python 中对序列的切片访问默认为左闭右开,现自定义实现为左闭右闭。

        自定义序列的相关魔法方法允许我们自己创建的类拥有序列的特性,让其使用起来就像 Python 的内置序列(dict,tuple,list,string 等)。
        如果要实现这个功能,就要遵循 python 的相关的协议。所谓的协议就是一些约定内容。例如,如果要将一个类要实现迭代,可以实现 __iter__() 或者 __getitem__() 其中一个方法。
        例子:自定义一个可以被切片的 SequenceNew 类:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import numbers

"""
举个例子:新建类并修改其实例的切片访问
    Python 中对序列的切片访问,是左闭右开。
    现需要:
        创建一个可被迭代的类(如果要实现这个功能,就要遵循 python 的相关的协议。所谓的协议就是一些约定内容。例如,如果要将一个类要实现迭代,可以实现__iter__() 或者 __getitem__()其中一个方法)
        改变默认的切片访问方式为左闭右闭
        举例:c1=youclassname([0,1,2,3,4,5,6,7,8,9])
        c1[2:7] 返回2,3,4,5,6,7
"""

class SequenceNew(object):

    def __init__(self, sequence_list):
        self.__sequence_list = sequence_list
        self.__list_index = 0

    # 实现了这个魔法函数,就可以是获取类中某个可迭代元素的下标的元素,也可以使其成为一个可迭代对象
    def __getitem__(self, item):
        # 使用相对编码,进行类型获取
        cls = type(self)
        # 判断传递进来的是slice类型还是int类型,返回不同的类型和操作
        if isinstance(item, slice):
            # 左闭右闭的关键实现:[item.start : item.stop : item.step] 。即:class slice(start, stop[, step])
            return cls(sequence_list = self.__sequence_list[item.start : item.stop + 1])
        elif isinstance(item, numbers.Integral):
            return cls(sequence_list = [self.__sequence_list[item]])

    # 返回容器的长度。可变和不可变容器都要实现它,这是协议的一部分
    def __len__(self):
        return len(self.__sequence_list)

    # 实现该魔法函数,可以使这个类成为一个可迭代的对象:对象实现了一个__iter__方法,这个方法负责返回一个迭代器
    def __iter__(self):
        return iter(self.__sequence_list)


    # 迭代器:内部实现了next(python3.x为__next__)方法,真正负责迭代的实现。当迭代器内的元素用尽之后,任何的进一步调用都之后触发 StopIteration 异常,所以迭代器需要一个__iter__方法来返回自身
    def __next__(self):
        try:
            i = self.__sequence_list[self.__list_index]
        except IndexError:
            raise StopIteration
        self.__list_index += 1
        return i


sn = SequenceNew([0,1,2,3,4,5,6,7,8,9])
print([ i for i in sn[2:7]])

以下是输出结果:

[2, 3, 4, 5, 6, 7]
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值