4.python自定义序列

本文详细介绍了Python序列的分类,包括可变序列与不可变序列,如list、tuple、str等,并探讨了序列操作中`+`与`+=`的区别,指出`+=`实际上是通过extend实现的。同时,讲解了可切片对象的实现原理,如何通过abc模块的Sequence类实现。还讨论了bisect模块在维护排序序列中的应用,以及array模块的使用限制和功能。最后,简要提到了列表推导式、生成器表达式和字典推导式这三种高效创建序列的方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1)序列类型的分类:

容器序列 list tuple deque
扁平序列 str bytes bytearray array.array
可变序列 list deque bytearray array
不可变序列 str tuple bytes


2)序列中+ ;+= extend的区别:

+与+=的区别,我们可以看下一下运行的代码

list = [1,2,3,4]
list2 = list + [5,6,7]
print(list2)
------------------------------------
[1, 2, 3, 4, 5, 6, 7]


list = [1,2,3,4]
list += [5,6,7]
print(list)
-------------------------------------
[1, 2, 3, 4, 5, 6, 7]



list = [1,2,3,4]
list2 = list + (5,6,7)
print(list2)
-------------------------------------
Traceback (most recent call last):
  File "E:\code\test.py", line 49, in <module>
    list2 = list + (5,6,7)
TypeError: can only concatenate list (not "tuple") to list




list = [1,2,3,4]
list += (5,6,7)
print(list)
---------------------------------------
[1, 2, 3, 4, 5, 6, 7]

可以看到+两边的序列类型要一致
+=是在原序列上操作而且不要求序列类型一致。

+=的实现是通过collections的abc模块中,MutableSequence类中的 def iadd(self, values)方法实现的,实际是用extend来实现的,extend内部是for循环实现的,下面是MutableSequence类中的代码片段。

    def __iadd__(self, values):
        self.extend(values)
        return self


    def extend(self, values):
        'S.extend(iterable) -- extend sequence by appending elements from the iterable'
        if values is self:
            values = list(values)
        for v in values:
            self.append(v)

可切片对象的实现:

实现可切片对象只要实现abc模块里面的Sequence类中的抽象方法就行

下面是Sequence类代码

class Sequence(Reversible, Collection):

    """All the operations on a read-only sequence.

    Concrete subclasses must override __new__ or __init__,
    __getitem__, and __len__.
    """

    __slots__ = ()

    @abstractmethod
    def __getitem__(self, index):
        raise IndexError

    def __iter__(self):
        i = 0
        try:
            while True:
                v = self[i]
                yield v
                i += 1
        except IndexError:
            return

    def __contains__(self, value):
        for v in self:
            if v is value or v == value:
                return True
        return False

    def __reversed__(self):
        for i in reversed(range(len(self))):
            yield self[i]

    def index(self, value, start=0, stop=None):
        '''S.index(value, [start, [stop]]) -> integer -- return first index of value.
           Raises ValueError if the value is not present.

           Supporting start and stop arguments is optional, but
           recommended.
        '''
        if start is not None and start < 0:
            start = max(len(self) + start, 0)
        if stop is not None and stop < 0:
            stop += len(self)

        i = start
        while stop is None or i < stop:
            try:
                v = self[i]
                if v is value or v == value:
                    return i
            except IndexError:
                break
            i += 1
        raise ValueError

    def count(self, value):
        'S.count(value) -> integer -- return number of occurrences of value'
        return sum(1 for v in self if v is value or v == value)

我们实现的方法如下:

import numbers
class group():
    def __init__(self,group_name,company_name,staffs):
        self.group_name = group_name
        self.company_name = company_name
        self.staffs = staffs

    def __reversed__(self):
        self.staffs.reverse()

    def __getitem__(self, item):
        cls = type(self)
        if isinstance(item,slice):
            return cls(group_name=self.group_name,company_name=self.company_name,staffs=self.staffs)
        elif isinstance(item,numbers.Integral):
            return cls(group_name=self.group_name, company_name=self.company_name, staffs=[self.staffs])

    def __len__(self):
        return len(self.staffs)

    def __iter__(self):
        return iter(self.staffs)

    def __contains__(self, item):
        if item in self.staffs:
            return True
        else:
            return False



if __name__ == '__main__':
    staffs = ['s','s','f','ddd','hdhdh']
    group = group('aaa','sss',staffs)
    print(group.staffs[2:])

bisect维护以排序序列

bisect插入的数值会保持排序,bisect插入两个相等的数值的时候默认是之前数值右侧插入。

import bisect
lis = []
bisect.insort(lis,1)
bisect.insort(lis,3)
bisect.insort(lis,23)
bisect.insort(lis,45)
bisect.insort(lis,76)
print(lis)
----------------------------------
[1, 3, 23, 45, 76]


'''
insor默认是使用insort_right方法,查看insort方法可以看到

insort = insort_right
def insort_right(*args, **kwargs): # real signature unknown
    """
    Insert item x in list a, and keep it sorted assuming a is sorted.
    
    If x is already in a, insert it to the right of the rightmost x.
    
    Optional args lo (default 0) and hi (default len(a)) bound the
    slice of a to be searched.
    """
    pass


def insort_left(*args, **kwargs): # real signature unknown
    """
    Insert item x in list a, and keep it sorted assuming a is sorted.
    
    If x is already in a, insert it to the left of the leftmost x.
    
    Optional args lo (default 0) and hi (default len(a)) bound the
    slice of a to be searched.
    """
    pass
'''



```python
import bisect
lis = []
bisect.insort(lis,1)
bisect.insort(lis,3)
bisect.insort(lis,23)
bisect.insort(lis,45)
bisect.insort(lis,76)
bisect.insort(lis,76)
bisect.insort_right(lis,3.0)

print(lis)
print(bisect.bisect_right(lis,76))
print(bisect.bisect_left(lis,76))
print(lis)
----------------------------------------
[1, 3.0, 3, 3.0, 23, 45, 76, 76]
8
6
[1, 3.0, 3, 3.0, 23, 45, 76, 76]
array的使用

1)arrey只能存放指定的数据类型

import array
my_arrey = array.array("i")
my_arrey.append(1)
my_arrey.append(2)
my_arrey.append(3)
print(my_arrey)
----------------------------------------
array('i', [1, 2, 3])

用pychar 查看 array实现以下接口

class array(MutableSequence[_T], Generic[_T]):
    typecode: _TypeCode
    itemsize: int
    @overload
    def __init__(self: array[int], typecode: _IntTypeCode, __initializer: Union[bytes, Iterable[_T]] = ...) -> None: ...
    @overload
    def __init__(self: array[float], typecode: _FloatTypeCode, __initializer: Union[bytes, Iterable[_T]] = ...) -> None: ...
    @overload
    def __init__(self: array[Text], typecode: _UnicodeTypeCode, __initializer: Union[bytes, Iterable[_T]] = ...) -> None: ...
    @overload
    def __init__(self, typecode: str, __initializer: Union[bytes, Iterable[_T]] = ...) -> None: ...
    def append(self, __v: _T) -> None: ...
    def buffer_info(self) -> Tuple[int, int]: ...
    def byteswap(self) -> None: ...
    def count(self, __v: Any) -> int: ...
    def extend(self, __bb: Iterable[_T]) -> None: ...
    if sys.version_info >= (3, 2):
        def frombytes(self, __buffer: bytes) -> None: ...
    def fromfile(self, __f: BinaryIO, __n: int) -> None: ...
    def fromlist(self, __list: List[_T]) -> None: ...
    def fromunicode(self, __ustr: str) -> None: ...
    def index(self, __v: _T) -> int: ...  # type: ignore  # Overrides Sequence
    def insert(self, __i: int, __v: _T) -> None: ...
    def pop(self, __i: int = ...) -> _T: ...
    if sys.version_info < (3,):
        def read(self, f: BinaryIO, n: int) -> None: ...
    def remove(self, __v: Any) -> None: ...
    def reverse(self) -> None: ...
    if sys.version_info >= (3, 2):
        def tobytes(self) -> bytes: ...
    def tofile(self, __f: BinaryIO) -> None: ...
    def tolist(self) -> List[_T]: ...
    def tounicode(self) -> str: ...
    if sys.version_info < (3,):
        def write(self, f: BinaryIO) -> None: ...
    if sys.version_info < (3, 9):
        def fromstring(self, __buffer: bytes) -> None: ...
        def tostring(self) -> bytes: ...
    def __len__(self) -> int: ...
    @overload
    def __getitem__(self, i: int) -> _T: ...
    @overload
    def __getitem__(self, s: slice) -> array[_T]: ...
    @overload  # type: ignore  # Overrides MutableSequence
    def __setitem__(self, i: int, o: _T) -> None: ...
    @overload
    def __setitem__(self, s: slice, o: array[_T]) -> None: ...
    def __delitem__(self, i: Union[int, slice]) -> None: ...
    def __add__(self, x: array[_T]) -> array[_T]: ...
    def __ge__(self, other: array[_T]) -> bool: ...
    def __gt__(self, other: array[_T]) -> bool: ...
    def __iadd__(self, x: array[_T]) -> array[_T]: ...  # type: ignore  # Overrides MutableSequence
    def __imul__(self, n: int) -> array[_T]: ...
    def __le__(self, other: array[_T]) -> bool: ...
    def __lt__(self, other: array[_T]) -> bool: ...
    def __mul__(self, n: int) -> array[_T]: ...
    def __rmul__(self, n: int) -> array[_T]: ...
    if sys.version_info < (3,):
        def __delslice__(self, i: int, j: int) -> None: ...
        def __getslice__(self, i: int, j: int) -> array[_T]: ...
        def __setslice__(self, i: int, j: int, y: array[_T]) -> None: ...

ArrayType = array
列表推导式
old_list = [i for i in range(30) if i % 2 == 1]
print(old_list)
--------------------------------------------------------------
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29]



def handle(item):
    return item * 3

old_list = [handle(i) for i in range(30) if i % 2 == 1]
print(type(old_list))
print(old_list)
---------------------------------------------------------------
<class 'list'>
[3, 9, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 75, 81, 87]

生成器表达式
def handle(item):
    return item * 3

old_list = (handle(i) for i in range(30) if i % 2 == 1)
print(type(old_list))
print(old_list)

for item in old_list:
    print(item)
-------------------------------------------------------
<class 'generator'>
<generator object <genexpr> at 0x00000152CC632660>
3
9
15
21
27
33
39
45
51
57
63
69
75
81
87

字典推导式
#将key与value替换位置
dict_key = {'a':1,'b':2,'c':3}
rerversed_dict = {value:key for key,value in dict_key.items()}
print(rerversed_dict)
----------------------------------------------------
{1: 'a', 2: 'b', 3: 'c'}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值