python 3.x 自定义序列

python 3.x 自定义序列

自定义序列

序列是python中非常重要的协议(python基于协议来编程的)

与容器相关的数据结构,它的抽象基类都是放在collections下的abc模块

abc下的_collections_abc的__all__中定义了collections相关的抽象基类

1 __all__ = ["Awaitable", "Coroutine",

2 "AsyncIterable", "AsyncIterator", "AsyncGenerator",

3 "Hashable", "Iterable", "Iterator", "Generator", "Reversible",

4 "Sized", "Container", "Callable", "Collection",

5 "Set", "MutableSet",

6 "Mapping", "MutableMapping",

7 "MappingView", "KeysView", "ItemsView", "ValuesView",

8 "Sequence", "MutableSequence",

9 "ByteString",

10 ]

与序列相关的抽象基类

Sequence(不可变的序列) --> class Sequence(Reversible, Collection):

Reversible类源码

1 class Reversible(Iterable):

2

3 __slots__ = ()

4

5 @abstractmethod

6 def __reversed__(self):

7 while False:

8 yield None

9

10 @classmethod

11 def __subclasshook__(cls, C):

12 if cls is Reversible:

13 return _check_methods(C, "__reversed__", "__iter__")

14 return NotImplemented

Sized源码

1 class Sized(metaclass=ABCMeta):

2

3 __slots__ = ()

4

5 @abstractmethod

6 def __len__(self):

7 return 0

8

9 @classmethod

10 def __subclasshook__(cls, C):

11 if cls is Sized:

12 return _check_methods(C, "__len__")

13 return NotImplemented

Iterable源码

1 class Iterable(metaclass=ABCMeta):

2

3 __slots__ = ()

4

5 @abstractmethod

6 def __iter__(self):

7 while False:

8 yield None

9

10 @classmethod

11 def __subclasshook__(cls, C):

12 if cls is Iterable:

13 return _check_methods(C, "__iter__")

14 return NotImplemented

Container源码

1 class Container(metaclass=ABCMeta):

2

3 __slots__ = ()

4

5 @abstractmethod

6 def __contains__(self, x):

7 return False

8

9 @classmethod

10 def __subclasshook__(cls, C):

11 if cls is Container:

12 return _check_methods(C, "__contains__")

13 return NotImplemented

Collection源码

1 class Collection(Sized, Iterable, Container):

2

3 __slots__ = ()

4

5 @classmethod

6 def __subclasshook__(cls, C):

7 if cls is Collection:

8 return _check_methods(C, "__len__", "__iter__", "__contains__")

9 return NotImplemented

Sequence源码

1 class Sequence(Reversible, Collection):

2

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

4

5 Concrete subclasses must override __new__ or __init__,

6 __getitem__, and __len__.

7 """

8

9 __slots__ = ()

10

11 @abstractmethod

12 def __getitem__(self, index):

13 raise IndexError

14

15 def __iter__(self):

16 i = 0

17 try:

18 while True:

19 v = self[i]

20 yield v

21 i += 1

22 except IndexError:

23 return

24

25 def __contains__(self, value):

26 for v in self:

27 if v is value or v == value:

28 return True

29 return False

30

31 def __reversed__(self):

32 for i in reversed(range(len(self))):

33 yield self[i]

34

35 def index(self, value, start=0, stop=None):

36 '''S.index(value, [start, [stop]]) -> integer -- return first index of value.

37 Raises ValueError if the value is not present.

38 '''

39 if start is not None and start < 0:

40 start = max(len(self) + start, 0)

41 if stop is not None and stop < 0:

42 stop += len(self)

43

44 i = start

45 while stop is None or i < stop:

46 try:

47 v = self[i]

48 if v is value or v == value:

49 return i

50 except IndexError:

51 break

52 i += 1

53 raise ValueError

54

55 def count(self, value):

56 'S.count(value) -> integer -- return number of occurrences of value'

57 return sum(1 for v in self if v is value or v == value)

58

59 Sequence.register(tuple)

60 Sequence.register(str)

61 Sequence.register(range)

62 Sequence.register(memoryview)

通过以上的源码

Sequence继承两个类Reversible, Collection

Reversible: 中定义抽象魔法函数@abstractmethod >> def __reversed__(self): >> while False: >> yield None, 数据的反转 如: abc --> cba

Collection: 继承三个类 --> class Collection(Sized, Iterable, Container):

Sized( class Sized(metaclass=ABCMeta): )中定义了抽象魔法函数@abstractmethod >> def __len__(self): >> return 0,这样可以计算Collection的长度.

Iterable( class Iterable(metaclass=ABCMeta): )中定义了抽象魔法函数@abstractmethod >> def __iter__(self): >> while False: >> yield None,这样可以对Collection进行迭代(for循环)

Container( class Container(metaclass=ABCMeta): )中定义了抽象魔法函数@abstractmethod >> def __contains__(self, x): >> return False 有了__contains__()方法,可以使用if...in...来做判断,(比如说判断一个数据是否在list里面)如果没有__contains__()魔法函数,但是定义了__getitem__()魔法函数,实际上也可以使用if...in..来进行判断.

if...in...对python解释器来说,python解释器首选的就是Container中的__contains__()魔法函数,如果没有的话,退一步,去找__getitem__()魔法函数,然后通过__getitem__()魔法函数遍历整个序列(python在内部做了很多的优化)

通过查看Sequence的源码可以知道对于不可变序列类型来说,

继承Reversible实现抽象魔法函数__reversed__()

继承Collection.实现抽象魔法函数__contains__()和__iter__(),而抽象魔法函数__len__()需要Sequence的子类来实现

Sequence中的抽象魔法函数__getitem__()需要子类来实现,以及构造函数__init__().

MutableSequence(可变的序列) --> class MutableSequence(Sequence):

MutableSequence源码

1 class MutableSequence(Sequence):

2

3 __slots__ = ()

4

5 """All the operations on a read-write sequence.

6

7 Concrete subclasses must provide __new__ or __init__,

8 __getitem__, __setitem__, __delitem__, __len__, and insert().

9

10 """

11

12 @abstractmethod

13 def __setitem__(self, index, value):

14 raise IndexError

15

16 @abstractmethod

17 def __delitem__(self, index):

18 raise IndexError

19

20 @abstractmethod

21 def insert(self, index, value):

22 'S.insert(index, value) -- insert value before index'

23 raise IndexError

24

25 def append(self, value):

26 'S.append(value) -- append value to the end of the sequence'

27 self.insert(len(self), value)

28

29 def clear(self):

30 'S.clear() -> None -- remove all items from S'

31 try:

32 while True:

33 self.pop()

34 except IndexError:

35 pass

36

37 def reverse(self):

38 'S.reverse() -- reverse *IN PLACE*'

39 n = len(self)

40 for i in range(n//2):

41 self[i], self[n-i-1] = self[n-i-1], self[i]

42

43 def extend(self, values):

44 'S.extend(iterable) -- extend sequence by appending elements from the iterable'

45 for v in values:

46 self.append(v)

47

48 def pop(self, index=-1):

49 '''S.pop([index]) -> item -- remove and return item at index (default last).

50 Raise IndexError if list is empty or index is out of range.

51 '''

52 v = self[index]

53 del self[index]

54 return v

55

56 def remove(self, value):

57 '''S.remove(value) -- remove first occurrence of value.

58 Raise ValueError if the value is not present.

59 '''

60 del self[self.index(value)]

61

62 def __iadd__(self, values):

63 self.extend(values)

64 return self

65

66 MutableSequence.register(list)

67 MutableSequence.register(bytearray) # Multiply inheriting, see ByteString

通过MutableSequence源码

MutableSequence继承Sequence,所以MutableSequence的子类必须覆写Sequence类没有实现的抽象魔法函数__len__()和__getitem__().

以及MutableSequence类中的抽象魔法函数__setitem__()和__delitem__().以及抽象方法insert().以及构造函数__init__()

序列的+,+=和extend的区别

+ 运算符将两个列表合并且生成一个新的对象列表,新列表与原来合并的子列表互不影响.

+= 运算符内部实现了一个魔法函数__iadd__(self).

1 def __iadd__(self, values):

2 self.extend(values)

3 return self

4

5 # --------------------------------------------------------------------------------------

6

7 def extend(self, values):

8 'S.extend(iterable) -- extend sequence by appending elements from the iterable'

9 for v in values:

10 self.append(v)

11

12 # --------------------------------------------------------------------------------------

13

14 def append(self, value):

15 'S.append(value) -- append value to the end of the sequence'

16 self.insert(len(self), value)

17

18 # --------------------------------------------------------------------------------------

19

20 @abstractmethod

21 def insert(self, index, value):

22 'S.insert(index, value) -- insert value before index'

23 raise IndexError

通过源码: += 运算符内部实现了一个魔法函数__iadd__(self).而__iadd__()魔法函数中调用extend()方法,extend()方法将传递进来的可迭代的数据,进行for循环遍历, 使用append(len(self),value)方法将可迭代的数据元素逐一添加到原有序列的后面append()函数内部调用insert()方法,insert()的意思是将插入的元素,放到指定索引值处

1 # 初始化list的两种方式

2 a = [1, 2]

3 # 空列表

4 b = list([9, 8])

5

6 # 将两个列表相加并产生一个新的对象c,新列表与原来的子列表互不影响

7 c = a + [3, 4]

8

9 # 结果: [1, 2, 3, 4]

10 print(c)

11

12 # 报错: TypeError: can only concatenate list (not "tuple") to list

13 # 只能将list和list数据类型想合并.

14 # d = a + (11, 22)

15

16 # ------------------------------------------------------------------------

17

18 # += 运算符实现两列表合并是在原有的列表上添加一个列表的所有元素

19 a += [5, 6]

20 # 结果: [1, 2, 5, 6]

21 print(a)

22

23 a += (11, 22)

24 # 结果: [1, 2, 5, 6, 11, 22]

25 print(a)

26

27 # ------------------------------------------------------------------------

28

29 # extend() 与 append()区别

30 # extend()将传递进来的序列对象,进行for循环遍历,将元素逐一添加的原有列表中

31 # append()将传递进来的数据当成一个元素,添加到原有列表的末端

32 b.extend([1, 2, 3])

33 c.append([1, 2, 3])

34

35 # b = [9,8]

36 # 结果: [9, 8, 1, 2, 3]

37 print(b)

38

39 # c = [1,2,3,4]

40 # 结果: [1, 2, 3, 4, [1, 2, 3]]

41 print(c)

实现可切片的对象

模式[start:end:step]

start: 表示切片的开始位置,默认为0

end : 表示切片截止(但不包含)位置,默认为列表的长度

step : 表示切片的步长,默认为1

当start为0时可省略

当end为列表长度时可省略

当step为1时可省略,并且省略步长时可以同时省略最后一个冒号.

注意: 当step为负整数时,表示反向切片,这时start值要比end值大才行.

所有切片取值的操作会返回一个新的列表

通过示例代码来体会切片的强大之处

a_list = [3, 4, 5, 6, 7, 9, 11, 13, 15, 17]

列表取值的操作

a_list[::] 返回包含原列表中所有元素的新列表

a_list[::-1] 返回包含原列表中所有元素的逆序列表

a_list[::2] 隔一个取一个,获取偶数位置的元素

a_list[1::2] 隔一个取一个,获取奇数位置的元素

a_list[3:6] 指定切片的开始和结束的位置

a_list[0:100] 切片结束位置大于列表长度时,从列表尾部截断

a_list[100:] 切片开始位置大于列表长度时,返回空列表

列表修改(赋值)操作

a_list[len(a_list):] = [9] 在列表尾部增加元素

a_list[:0] = [1, 2] 在列表头部插入元素

a_list[3:3] = [88] 在列表中间指定位置插入元素

a_list[:3] = [1, 2] 替换列表元素,等号两边的列表长度相等

a_list[3:] = [4, 5, 6] 等号两边的列表长度也可以不相等

a_list[::2] = [0] * 5 隔一个修改一个

a_list[::2] = ['a', 'b', 'c', 'd', 'e'] 隔一个修改一个

a_list[::2] = [1, 2, 3] 左侧切片不连续,等号两边列表长度必须相等,不然会报错 : ValueError: attempt to assign sequence of size 3 to extended slice of size 5 (尝试将大小为3的序列分配给大小为5的扩展切片)

a_list[:3] = [] 删除列表中前3个元素

del a_list[:3] 切片元素连续

del a_list[::2] 切片元素不连续,隔一个删一个

1 a_list = [3, 4, 5, 6, 7, 9, 11, 13, 15, 17]

2

3 # ------------------------------------------------------

4 # 列表取值的操作

5

6 # 返回包含原列表中所有元素的新列表

7 # 结果: [3, 4, 5, 6, 7, 9, 11, 13, 15, 17]

8 print(a_list[::])

9

10 # 返回包含原列表中所有元素的逆序列表

11 # 结果: [17, 15, 13, 11, 9, 7, 6, 5, 4, 3]

12 print(a_list[::-1])

13

14 # 隔一个取一个,获取偶数位置的元素

15 # 结果: [3, 5, 7, 11, 15]

16 print(a_list[::2])

17

18 # 隔一个取一个,获取奇数位置的元素

19 # 结果: [4, 6, 9, 13, 17]

20 print(a_list[1::2])

21

22 # 指定切片的开始和结束的位置

23 # 结果: [6, 7, 9]

24 print(a_list[3:6])

25

26 # 切片结束位置大于列表长度时,从列表尾部截断

27 # 结果: [3, 4, 5, 6, 7, 9, 11, 13, 15, 17]

28 print(a_list[0:100])

29

30 # 切片开始位置大于列表长度时,返回空列表

31 # 结果: []

32 print(a_list[100:])

33

34 # ------------------------------------------------------

35 # 列表修改(赋值)操作

36

37 # 在列表尾部增加元素

38 a_list[len(a_list):] = [9]

39 # 结果: [3, 4, 5, 6, 7, 9, 11, 13, 15, 17, 9]

40 print(a_list)

41

42 # 在列表头部插入元素

43 a_list[:0] = [1, 2]

44 # 结果: [1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 15, 17]

45 print(a_list)

46

47 # 在列表中间指定位置插入元素

48 a_list[3:3] = [88]

49 # 结果: [3, 4, 5, 88, 6, 7, 9, 11, 13, 15, 17]

50 print(a_list)

51

52 # 替换列表元素,等号两边的列表长度相等

53 a_list[:3] = [1, 2]

54 # 结果: [1, 2, 6, 7, 9, 11, 13, 15, 17]

55 print(a_list)

56

57 # 等号两边的列表长度也可以不相等

58 a_list[3:] = [4, 5, 6]

59 # 结果: [3, 4, 5, 4, 5, 6]

60 print(a_list)

61

62 # 隔一个修改一个

63 a_list[::2] = [0] * 5

64 # 结果: [0, 4, 0, 6, 0, 9, 0, 13, 0, 17]

65 print(a_list)

66

67 # 隔一个修改一个

68 a_list[::2] = ['a', 'b', 'c', 'd', 'e']

69 # 结果: ['a', 4, 'b', 6, 'c', 9, 'd', 13, 'e', 17]

70 print(a_list)

71

72 # 左侧切片不连续,等号两边列表长度必须相等

73 # 不然会报错 : ValueError: attempt to assign sequence of size 3 to extended slice of size 5

74 # 尝试将大小为3的序列分配给大小为5的扩展切片

75 a_list[::2] = [1, 2, 3]

76

77 # 删除列表中前3个元素

78 a_list[:3] = []

79 # 结果: [6, 7, 9, 11, 13, 15, 17]

80 print(a_list)

81

82 # 切片元素连续

83 del a_list[:3]

84 # 结果: [6, 7, 9, 11, 13, 15, 17]

85 print(a_list)

86

87 # 切片元素不连续,隔一个删一个

88 del a_list[::2]

89 # 结果: [4, 6, 9, 13, 17]

90 print(a_list)

自定义切片对象

魔法函数def __getitem__(self, item)是实现切片的关键.

如果一个对象没有实现魔法函数def __getitem__(self, item),对其执行切片的操作,会报错TypeError: 'Group' object is not subscriptable("Group"对象没有下标)

1 """

2 自定义切片对象

3

4 组的概念(生活中常见的概念)

5 比如学校里的学习小组,公司里的开发组,Django里的用户分组(Django里的Group是管理用户的user)

6

7 需求: 定义一个类Group,希望Group支持切片操作,Group类是不可修改的序列

8 """

9

10

11 class Group:

12 """

13 自定义不可变序列,需要实现的魔法函数

14 __reversed__()

15 __getitem__()

16 __len__()

17 __iter__()

18 __contains__()

19 """

20

21 def __init__(self, group_name, company_name, staffs):

22 self.group_name = group_name

23 self.company_name = company_name

24 self.staffs = staffs

25

26 def __reversed__(self):

27 pass

28

29 def __getitem__(self, item):

30 """

31 对Group做切片操作,将切片的参数传递给__getitem__()方法中

32 但是有一个问题存在,python的list进行切片操作后还是list对象.

33 而此时对Group做切片操作返回的不是Group对象,而是list.

34

35 所以希望Group进行切片操作后还是一个Group对象,这样的话,就可以不停的对Group对象进行切片操作.

36 """

37 # sub_group = group[:2] --> group[:2:] --> group[None:2:None]

38 # item = {slice}slice(None, 2, None)

39 return self.staffs[item]

40

41 def __len__(self):

42 pass

43

44 def __iter__(self):

45 pass

46

47 def __contains__(self, item):

48 pass

49

50

51 lang_staffs = ["python", "java", "php", "android"]

52 group = Group("computer", "language", lang_staffs)

53

54 # debug : sub_group = {list}: ['python', 'java']

55 sub_group = group[:2]

56

57 # 结果: ['python', 'java'] 对Group对象进行切片操作,返回的结果类型不是Group而是list,这不是我们希望得到的数据类型.

58 print(sub_group)

1 """

2 自定义切片对象

3 需求: 定义一个类Group,希望Group支持切片操作,Group类是不可修改的序列

4 Group进行进行切片操作后,获取的结果类型还是一个Group类型

5 """

6 import numbers

7

8

9 class Group:

10 """

11 自定义不可变序列,需要实现的魔法函数

12 __reversed__()

13 __getitem__()

14 __len__()

15 __iter__()

16 __contains__()

17 """

18

19 def __init__(self, group_name, company_name, staffs):

20 self.group_name = group_name

21 self.company_name = company_name

22 self.staffs = staffs

23

24 def __reversed__(self):

25 pass

26

27 def __getitem__(self, item):

28 """

29 希望Group进行切片操作后还是一个Group对象,这样的话,就可以不停的对Group对象进行切片操作.

30

31 当进行切片操作的时候,python解释器会将切片初始化一个slice对象,然后将slice对象传递给__getitem__()

32 魔法函数的item.

33

34 当给序列对象指定索引操作(group[0])时,__getitem__()魔法函数的item将接收一个int类型的值.

35 """

36 # 获取当前self的class

37 cls = type(self)

38 if isinstance(item, slice):

39 return cls(group_name=self.group_name, company_name=self.company_name, staffs=self.staffs[item])

40

41 elif isinstance(item, numbers.Integral):

42

43 # self.staffs[item] --> 得到的结果是一个数字 --> 将其变成一个数组[self.staffs[item]]

44 # 因为Group只接收数组,才能不断的做切片操作

45 return cls(group_name=self.group_name, company_name=self.company_name, staffs=[self.staffs[item]])

46

47 def __len__(self):

48 pass

49

50 def __iter__(self):

51 pass

52

53 def __contains__(self, item):

54 pass

55

56

57 lang_staffs = ["python", "java", "php", "android"]

58 group = Group("computer", "language", lang_staffs)

59

60 # debug:

61 # sub_group = {Group} <__main__.Group object at 0x0000000003657C18>

62 # company_name = {str} 'language'

63 # group_name = {str} 'computer'

64 # staffs = {list} : ['python', 'java']

65 sub_group = group[:2]

66

67 # debug:

68 # sub_group1 = {Group} <__main__.Group object at 0x00000000024102B0>

69 # company_name = {str} 'language'

70 # group_name = {str} 'computer'

71 # staffs = {list} : ['python']

72 sub_group1 = group[0]

1 """

2 自定义序列对象

3 需求: 定义一个类Group,Group支持切片操作,Group类是不可修改的序列

4 """

5 import numbers

6

7

8 class Group:

9 """

10 自定义不可变序列,需要实现的魔法函数

11 __reversed__()

12 __getitem__()

13 __len__()

14 __iter__()

15 __contains__()

16 """

17

18 def __init__(self, group_name, company_name, staffs):

19 self.group_name = group_name

20 self.company_name = company_name

21 self.staffs = staffs

22

23 def __reversed__(self):

24 self.staffs.reverse()

25

26 def __getitem__(self, item):

27 cls = type(self)

28 if isinstance(item, slice):

29 return cls(group_name=self.group_name, company_name=self.company_name, staffs=self.staffs[item])

30 elif isinstance(item, numbers.Integral):

31 return cls(group_name=self.group_name, company_name=self.company_name, staffs=[self.staffs[item]])

32

33 def __len__(self):

34 # Group的长度委托数组来完成

35 return len(self.staffs)

36

37 def __iter__(self):

38 # 先这样写,后面文章会详细说明

39 return iter(self.staffs)

40

41 def __contains__(self, item):

42 # if...in...

43 if item in self.staffs:

44 return True

45 else:

46 return False

47

48

49 lang_staffs = ["python", "java", "php", "android"]

50 group = Group("computer", "language", lang_staffs)

51

52

53 def do_reversed():

54 """ 测试反转顺序 """

55 reversed(group)

56 do_iter()

57

58

59 def do_len():

60 """ 测试__len__() """

61 print(len(group))

62

63

64 def do_contains():

65 """ 测试__contains__() """

66 if "python" in group:

67 print("YES")

68 else:

69 print("NO")

70

71

72 def do_iter():

73 """ 测试__iter__() """

74 for item in group:

75 print(item)

76

77

78 # 结果: 4

79 do_len()

80

81 # 结果:

82 # python

83 # java

84 # php

85 # android

86 do_iter()

87

88 # 结果: YES

89 do_contains()

90

91 # 结果:

92 # android

93 # php

94 # java

95 # python

96 do_reversed()

bisect模块

作用 :

python中处理已排序的序列的查找模块,用来维护已排序的序列(可修改的序列)

排序的顺序是升序

始终维护一个已排序的序列

bisect中的方法都是通过二分查找算法实现的.

insort()与insort_right()是同一个方法

将一个数据插入到以排序的序列中,对序列进行修改.如果插入的数据在序列中已存在,那么插入到已存在数据的最右端

如: [1, 2, 2, 3]插入数据2(new) --> [1, 2, 2, 2(new), 3]

insort_left()

将一个数据插入到以排序的序列中,对序列进行修改.如果插入的数据在序列中已存在,那么插入到已存在数据的最左端

如: [1, 2, 2, 3]插入数据2(new) --> [1, 2(new), 2, 2, 3]

bisect()与bisect_right()是同一个方法

返回要插入的数据在已排序序列中要插入的索引值,未对序列进行修改.

如果插入的数据在序列中已存在,那么将返回插入到已存在数据的最右端的索引值

如: [1, 2, 2, 3]插入数据2(new) --> 返回要插入的索引值是3

bisect_left()

返回要插入的数据在已排序序列中要插入的索引值,未对序列进行修改.

如果插入的数据在序列中已存在,那么将返回插入到已存在数据的最左端的索引值

如: [1, 2, 2, 3]插入数据2(new) --> 返回要插入的索引值是1

1 import bisect

2

3 inter_list = []

4 bisect.insort(inter_list, 3)

5 bisect.insort(inter_list, 2)

6 bisect.insort(inter_list, 6)

7 bisect.insort(inter_list, 1)

8 bisect.insort(inter_list, 5)

9 bisect.insort(inter_list, 4)

10

11 # 结果: [1, 2, 3, 4, 5, 6]

12 print(inter_list)

1 import bisect

2

3 inter_list = []

4 bisect.insort(inter_list, 3)

5 bisect.insort(inter_list, 2)

6 bisect.insort(inter_list, 6)

7 bisect.insort(inter_list, 1)

8 bisect.insort(inter_list, 5)

9 bisect.insort(inter_list, 4)

10

11 # 结果: 插入到索引值为2的位置上

12 print(bisect.bisect_left(inter_list, 3))

13

14 # 结果: 插入到索引值为3的位置上

15 print(bisect.bisect(inter_list, 3))

16

17 # 结果: [1, 2, 3, 4, 5, 6]

18 # 通过结果证明执行bisect_left()和bisect()这两方法,只是返回需要插入的数据应插入到已排序序列的索引值,

19 # 并没有对已排序的序列进行修改.

20 print(inter_list)

1 import bisect

2 from collections import deque

3

4 inter_list = deque()

5 bisect.insort(inter_list, 'python')

6 bisect.insort(inter_list, 'java')

7 bisect.insort(inter_list, 'php')

8 bisect.insort(inter_list, 'android')

9 bisect.insort(inter_list, 'ios')

10 bisect.insort(inter_list, 'c++')

11

12 # 4

13 print(bisect.bisect_left(inter_list, 'php'))

14 bisect.insort_left(inter_list, 'php')

15

16 # 结果: deque(['android', 'c++', 'ios', 'java', 'php', 'php', 'python'])

17 print(inter_list)

array(数组)模块

数组是连续的内存空间,它的性能非常的高

在做数据处理或者算法,用array特别多,因为array的效率和性能比list高很多.

array只能存放指定的数据类型

append() ----------- append a new item to the end of the array

buffer_info() ------ return information giving the current memory info

byteswap() --------- byteswap all the items of the array

count() ------------ return number of occurrences of an object

extend() ----------- extend array by appending multiple elements from an iterable

fromfile() --------- read items from a file object

fromlist() --------- append items from the list

frombytes() -------- append items from the string

index() ------------ return index of first occurrence of an object

insert() ----------- insert a new item into the array at a provided position

pop() -------------- remove and return item (default last)

remove() ----------- remove first occurrence of an object

reverse() ---------- reverse the order of the items in the array

tofile() ----------- write all items to a file object

tolist() ----------- return the array converted to an ordinary list

tobytes() ---------- return the array converted to a string

1 import array

2

3 a_list = [11, 22, 33]

4 b_list = [44, 55, 66]

5

6 my_array = array.array("i")

7

8 my_array.append(1)

9 my_array.append(2)

10 my_array.append(4)

11 my_array.append(6)

12 my_array.append(3)

13 my_array.append(6)

14

15 # 结果: array('i', [1, 2, 4, 6, 3, 6])

16 print(my_array)

17

18 # 结果: (34258736, 6)

19 print(my_array.buffer_info())

20

21 # 结果: 6在数组中出现的次数 2

22 print(my_array.count(6))

23

24 # 将序列中的元素逐一添加到数组的后面

25 my_array.extend(a_list)

26 # 结果: array('i', [1, 2, 4, 6, 3, 6, 11, 22, 33])

27 print(my_array)

28

29 # 将列表中的元素逐一添加到数组的后面

30 my_array.fromlist(b_list)

31 # 结果: array('i', [1, 2, 4, 6, 3, 6, 11, 22, 33, 44, 55, 66])

32 print(my_array)

33

34 # 将字节转换成机器码

35 my_array.frombytes(bytes(4))

36 # 结果: array('i', [1, 2, 4, 6, 3, 6, 11, 22, 33, 44, 55, 66, 0])

37 print(my_array)

38

39 # 报错: ValueError: bytes length not a multiple of item size

40 # 字节长度不是项大小的倍数

41 # my_array.frombytes(bytes(3))

42

43 # 将第一个匹配的元素的索引值返回

44 index1 = my_array.index(6)

45 # 结果: 3

46 print(index1)

47

48 # 将元素77添加到指定索引的位置上. insert(索引值,元素)

49 my_array.insert(0, 77)

50 # 结果: array('i', [77, 1, 2, 4, 6, 3, 6, 11, 22, 33, 44, 55, 66, 0])

51 print(my_array)

52

53 # pop()方法默认移除最后一个元素,并将移除的元素返回

54 pop_a = my_array.pop()

55 # 结果: 0

56 print(pop_a)

57 # 结果: array('i', [77, 1, 2, 4, 6, 3, 6, 11, 22, 33, 44, 55, 66])

58 print(my_array)

59

60 # pop()可以指定要移除元素的索引值,并将移除的元素返回

61 pop_b = my_array.pop(3)

62 # 结果: 4

63 print(pop_b)

64 # 结果: array('i', [77, 1, 2, 6, 3, 6, 11, 22, 33, 44, 55, 66])

65 print(my_array)

66

67 # remove() 删除第一次匹配的元素,不返回删除的元素.

68 # 如果删除的元素不存在,报错ValueError: array.remove(x): x not in list

69 array_remove = my_array.remove(6)

70 # 结果: None

71 print(array_remove)

72 # 结果: array('i', [77, 1, 2, 3, 6, 11, 22, 33, 44, 55, 66])

73 print(my_array)

74

75 # 将数组倒序

76 my_array.reverse()

77 # 结果: array('i', [66, 55, 44, 33, 22, 11, 6, 3, 2, 1, 77])

78 print(my_array)

79

80 # 将数组转化成列表

81 tolist = my_array.tolist()

82 # 结果: [66, 55, 44, 33, 22, 11, 6, 3, 2, 1, 77]

83 print(tolist)

列表推导式,字典推导式,生成器

1 """

2 列表推导式(列表生成式)

3 通过一行代码来生成列表

4

5 range(n)从零开始,到n-1截止

6

7 列表推导式的出现,可以取代map,reduce,filter函数式编程

8 """

9

10 # 需求: 提取1~20之间的奇数

11 a_list = [x for x in range(21) if x % 2 == 1]

12 # 结果: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

13 print(a_list)

14

15 # --------------------------------------------------------------------------------

16

17 # 使用filter + map 函数式编程,需要两行代码.

18 filter_pattern = filter(lambda x: True if x % 2 == 1 else False, range(21))

19 map_obj = map(lambda x: x, list(filter_pattern))

20 # 结果: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

21 print(list(map_obj))

1 """

2 字典推导式(字典生成式)

3 通过一行代码来生成字典

4 """

5

6 # 需求: 将字典的key,value颠倒

7 my_dict = {"python": 22, "java": 24, "php": 8}

8

9 result_dict = {value: key for key, value in my_dict.items()}

10 # {22: 'python', 24: 'java', 8: 'php'}

11 print(result_dict)

12

13

14

15 # 需求将字典的key放到set()集合中

16 key_set = {key for key in my_dict}

17 # 结果:

18 print(type(key_set))

19 # 结果: {'php', 'python', 'java'}

20 print(key_set)

21

22

23

24 # 第二种方法,使用字典的内置方法

25 key_set1 = set(my_dict.keys())

26 # 结果:

27 print(type(key_set1))

28 # {'python', 'php', 'java'}

29 print(key_set1)

1 """

2 推导式变成生成器

3 """

4

5 # 需求: 从0~20中取出所有的可以被5整除的元素的生成器

6 my_gen = (x for x in range(21) if x % 5 == 0)

7 # 结果:

8 print(type(my_gen))

9 # 结果: [0, 5, 10, 15, 20]

10 print(list(my_gen))

********

相关推荐

软考出成绩需要多久?全面解析与常见问题解答
365bet体育投注网站

软考出成绩需要多久?全面解析与常见问题解答

电脑无法连接wifi网络是怎么回事?试试这五种解决方案
365速发国际平台登陆

电脑无法连接wifi网络是怎么回事?试试这五种解决方案

《新征战手游》职业选择指南
365bet体育投注网站

《新征战手游》职业选择指南

下午6点!FIFA官宣,中国主办世界杯悬念曝光,保送国足,创历史
365dni讲解

下午6点!FIFA官宣,中国主办世界杯悬念曝光,保送国足,创历史

苹果手机怎么换手机卡
365速发国际平台登陆

苹果手机怎么换手机卡

“莼叶细如弦”的意思及全诗出处和翻译赏析
365bet体育投注网站

“莼叶细如弦”的意思及全诗出处和翻译赏析