Python说文解字_杂谈06

 1. 序列类型的分类:

  容器类型:list、tuple,deque

  扁平序列:str、bytes、bytearray、array.array

  可变序列:list、dequte、bytearray、array

  不可变序列:str、tuple、bytes

 

2. 序列的abc继承关系:

  魔法函数构成了协议

 

3.序列的+ +=和extend的区别:

my_list = []
my_list.append(1)
my_list.append("a")

from collections import abc

a = [1,2]
# a = list()
c = a + [3,4]
# c = a + (3,4)  # 抛异常
print(c)


# 就地加
a += [3,4]
a += (3,4)  # 可以为任意的序列类型
a.extend((3,4))
# def __iadd__(self, values):
#     self.extend(values)
#     return self
a.append((1,2,4))
print(a) 

  记住:我们知道类函数的实现是通过魔法函数来实现的。其中+号表示的是同类项的相加。

  记住:+=和extend是一样的,因此+=是通过__iadd__来实现extend的。

  记住:append表示添加的是元素位置。

  记住:不能用变量名去接收这些方法,因为没有返回值(aa = a.extend是错误的)

 

4. 实现可切片的对象:

# 模式[start:end:step]
r"""
    其中,第一个数字start表示切片开始位置,默认是0
    第二个数字end表示切片截止(但不包含)位置(默认为列表长度】
    第三个数字step表示切片的步长(默认为1)
    当start为0时可以省略,当end为列表长度时可以省略。
    当start为1时可以生路,并且省略步长时可以同时省略最后一个冒号。
    另外,当step为负整数时,表示反向切片,这时start应该比end的值要大才行。
"""
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]
print(aList) # 在列表头部插入元素
aList[3:3] = [4]
print(aList) # 在列表中间位置插入元素
aList[:3] = [1,2]
print(aList) #替换元素列表元素,等号两边的里诶包长度相同
aList[3:] = [4,5,6]
print(aList) # 等号两边的列表长度也可以不相等
aList[::2] = [0] * 3  # 将元素赋值三份
print(aList) # 隔一个修改一个
aList[::2] = ['a','b','c'] # 隔一个修改一个
print(aList)
# aList[::2] = [1,2] # 左侧切片不连续,等号两边列表长度必须相等
aList[:3] = [] #删除列表中前3个元素
del aList[:3] # 切片元素连续
del aList[::3] # 切片元素不连续,隔一个删一个。
print(aList)

 

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[item])
        elif isinstance(item,numbers.Integral):
            return cls(group_name=self.group_name,company_name=self.company_name,staffs=[self.staffs[item]])

    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


staffs = ["bobby1","imooc","bobby2","bobby3"]
group = Group(company_name="imooc",group_name="user",staffs=staffs)
sub_group = group[:2]
print(group.staffs)
# sub_group1 = group[0]
# print(group.staffs)
# reversed(group)
# for user in group:
#     print(user)

  记住:这是一个比较多的用魔法函数实现切片操作。

  记住:难理解的是cls = type(self),返回值:<class '__main__.Group'>,这是拿到类的对象 ,其实可以改写成下面方式

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

 

  记住:但是这里为什么要用type返回类对象呢?这是一种相对方式,为的是如果更改类名可以不用修改内部的代码。

 

5. bisect二分迭代类型操作:

import bisect
from collections import deque

# 用来处理已排序的序列,始终用来维持已排序的序列,升序。
# 二分查找
inter_list = []
bisect.insort(inter_list,3)
bisect.insort(inter_list,2)
bisect.insort(inter_list,5)
bisect.insort(inter_list,1)
bisect.insort(inter_list,6)


print(inter_list)
# 总结:
# bisect.bisect(data,1)
# 作用,查找该数值将会插入的位置并返回,而不会插入,返回是会在那个数字之后插入
# 表示:num > .... 插入
a1 = bisect.bisect(inter_list,4)
print(a1)

# bisect_left 和 bisect_right 函数
# 该函数用入处理将会插入重复数值的情况,返回将会插入的位置
# 第一:从左边看num>...插入位置
# 第二:从右边看 ... < num 出入位置。
a2 = bisect.bisect_left(inter_list,2)
print(a2)
a3 = bisect.bisect_right(inter_list,2)
print(a3)

# insort  函数 insort_left  和 insort_right
bisect.insort(inter_list,2)
print(inter_list)

 

7.数组:

# array, deque
# 数组:存储连续的内存空间,效率非常高的。
import array
# array 和list的一个重要区别,array只能存放指定的数据类型。
# array的性能比list高。

my_array = array.array("i")
my_array.append(1)
my_array.append("abc")
print(my_array)

 

  记住:我们是会用 列表,什么时候用数组

 

8. 列表推导式、生成器表达式、字典推导式、集合推导式。

# 列表生成式(列表推导式)
# 1. 提取1-20之间的奇数
odd_list = []
for i in range(21):
    if i %2 ==1:
        odd_list.append(i)

print(odd_list)


# 列表生成式
odd_list = [i for i in range(21) if i %2 == 1 ]

# 2.逻辑复杂的情况
def handle_item(item):
    return item * item

odd_list1 = [handle_item(i) for i in range(21) if i %2 == 1 ]

# 列表生成式性能高于列表操作。

 

  记住:列表生成式不能太复杂了。要不就放弃了可读性。另外列表生成式的操作高于列表操作。

 

# 生成器表达式:
odd_list = (i for i in range(21) if i %2 == 1 )
print(type(odd_list))
# <class 'generator'>
for item in odd_list:
    print(item)

  记住:生成器通过for循环打印出来。

odd_gen = (i for i in range(21) if i %2 == 1 )

odd_list = list(odd_gen)
print(odd_list)

  记住:生成器可以转回成list再打印出来也是可以的。

 

# 字典推导式
my_dict = {"bobby1":22,"bobby2":23,"imooc":5}
reversed_dict = {value:Key for Key,value in my_dict.items()}
print(reversed_dict)
# {22: 'bobby1', 23: 'bobby2', 5: 'imooc'}

 

 

# 集合推导式
# my_set = set(my_dict.keys())
my_set = {Key for Key,value in my_dict.items()}
print(my_set)
print(type(my_set))
# <class 'set'>

 

posted @ 2019-06-07 19:30  时海涛|Thomas  阅读(174)  评论(0编辑  收藏  举报