'''
内置序列类型
容器序列 : 能存放不同类型的数据
list
tuple
collections.deque
扁平序列 : 只能容纳一种类型
str
bytes
bytearray 字节数组
memoryview 内存镜像
arrayarray
可变序列: MutableSequence
list bytearray array.array collections.deque memoryview
不可变序列: Sequence
tuple str bytes
列表推导式 list comprehension: 快速生成一个列表
[.....]
生成器表达式 generator expression: 产生一个生成器
(....)
python解释器会忽略()[]{}中的换行符,所以可以省略续行符\
python3中不会出现变量泄漏问题
x = 1
lis = [ x for x in 'ABC')
x >>> 1 不会出现等于'C'的情况
x 类似于 函数中的局部变量 适用于循环结构,列表推导式等
'''
# 把一个字符串变成unicode码的列表
'''eg1:
symbols = '!#$&?'
codes = []
for symbol in symbols:
codes.append(ord(symbol))
print(codes)
codes2 = [ord(x) for x in symbols]
print(codes2)
'''
# 列表推导式和filter+map的比较
'''
symbols = '!#$&?你好吗'
beyond_ascii = [ord(x) for x in symbols if ord(x) > 127] # 非ascii字符
print(beyond_ascii)
beyond_ascii2 = list(filter(lambda x : x > 127,map(ord,symbols)))
print(beyond_ascii2)
'''
# 笛卡尔积 不同颜色海加尔尺码的T恤
colors = ['white','black','yellow']
sizes = 'S M L'.split()
tshirts = [(color,size) for color in colors for size in sizes]
print(tshirts)
tshirts1 = [(color,size) for size in sizes for color in colors] # 不同的顺序
print(tshirts1)
'''
生成器表达式
(......)
遵守迭代器协议,可以逐个地产出元素,而不是生成一个完整的列表,可以节约内存
'''
# 用生成器表达式建立元组和数组
'''
symbols = '!#$&?'
t = tuple(ord(x) for x in symbols) # 若生成器表达式是一个函数调用过程中的唯一参数,不用额外再加括号
print(t)
import array
a = array.array('I',(ord(x) for x in symbols)) # 两个参数,括号是必须的
print(a)
'''
# 用生成器表达式完全笛卡尔积
colors = ['white','black','yellow']
sizes = 'S M L'.split()
for tshirt in ('%s %s'%(c, s) for c in colors for s in sizes):
print(tshirt)
'''
元组:
1.元组其实是对数据的记录,元组中每个数据都是一条记录中一个字段的数据,外加这个字段的位置
拆包: a,b = 一个可迭代对象 也叫平行赋值
要求可迭代对象的元素个数和前面的元组的空档数一致
也可使用*来忽略不用的元素
2.作为不可变列表的元组
'''
# 把元组用作记录
'''
lax_coordinates = (33.9425,-118.408056)
city, year,pop,chg,area = ('Tokyo',2003,32450,0.66,8014) # 拆包
traveler_ids = [('USA','31195855'),
('BRA','CE3423567'),
('ESP','XDA2544350')]
for passport in sorted(traveler_ids):
print('%s %s'%(passport)) # 拆包
'''
# 拆包
'''
t = divmod(123,7)
print(t)
res = divmod(*t) # 拆包作为函数的参数
print(res)
import os
# os.path.split 返回一个路径+文件名的元组
_,filename = os.path.split('E:\pythonProjects\pythonProject\读书笔记\流畅的Python\01第二章 数据结构\03元组.py')
print(filename)
'''
# # *在拆包中的应用
# a,b,*rest = range(5)
# print(a,b,rest)
#
# a,b,*rest = range(3)
# print(a,b,rest)
#
# a,b,*rest = range(2)
# print(a,b,rest)
#
# # *只能用在一个变量名前面,但这个变量可以用在拆包的任意位置
# a,*body,c,d= range(5)
# print(a,body,c,d)
#
# *head,a,c,d= range(5)
# print(head,a,c,d)
# 嵌套元组拆包 获取经度 要求嵌套的结构相同
# metro_areas = [('Tokyo','JP',36.933,(35.689722,139.691667)),
# ('New Yory','US',20.104,(40.808611,-74.020386))]
# print('{:15} | {:^9} | {:^9}'.format('','lat.','long.'))
# fmt = '{:15} | {:9.4f} | {:9.4f}'
# for name,cc,pop,(latitude,longitude) in metro_areas:
# print(fmt.format(name,latitude,longitude))
# 具名元组 collections.namedtuple 用来构建一个带字段名的元组和一个有名字的类
# 定义和使用具名元组
'''
1.创建一个具名元组需要两个参数,一个是类名,另一个是各个字段的名字,后者可以是由字符串组成的可迭代对象
或者是空格分开的字符串
2.可以通过字段名或者位置来获取一个字段的信息
3.namedtuple的专有属性
_fields : 类名._fields 或者对象名._fields都可以调用,返回所有字段名的元组
_make(iterable) : 通过接受一个可迭代对象来生成一个类的实例,同City(*delhi_data)的效果相同
_asdict:把具名元组用collections.OrderedDict的形式返回
'''
#
# from collections import namedtuple
# City = namedtuple('City','name country population coordinnates') # 定义一个具名元组
# tokyo = City('Tokyo','JP',36.933,(35.68972,139.691667)) # 创建了一个具名元组
#
# print(tokyo)
# print(tokyo.name)
# print(tokyo[1])
# print(tokyo._fields)
#
# LatLong = namedtuple('LatLong','lat long')
# delhi_data = ('Delhi Ncr','IN',21.935,LatLong(28.613889,77.208889))
# delhi = City._make(delhi_data)
# print(delhi._asdict())
#
# for key,value in delhi._asdict().items():
# print(key+":"+str(value))
t = (1,3,2,4,2)
lis = [1,2,2,4,2,3,5]
print(reversed(t)) # tuple没有__reversed__方法,但任然可以调用这个方法
r = reversed(lis)
print(r.__next__()) # reversed方法返回的是一个迭代器
print(t)
print(lis)
print(dir(t))
'''为什么切片会忽略最后一个元素
1.快速看出切片里面由几个元素
lis[:3],range(3),3个元素
2.快速计算切片的长度 lis[1:5] end - start
3.利用任意一个小标来把序列分割成不重复的两部分 lis[:4]和lis[4:]
'''
# s = slice(1, 10, 2) # indexes 1,3,5,7,9
# print(type(s))
# print(s.__dir__())
# print(s.start)
# print(s.stop)
# print(s.step)
#
# s = slice(5) # indexes 0,1,2,3,4
# print(s.start)
# print(s.stop)
# print(s.step)
# 建立包含三个列表的列表
# lis = [[0]*3 for _ in range(3)]
# print(lis)
# lis[1][1] = 1
# print(lis)
#
# # 错误示范
# lst = [[0]*3]*3
# print(lst)
# lst[1][1] = 100
# print(lst) # lst实质是对[0,0,0]列表的三次引用
# +=谜题
# t = (1,2,[30,40])
# t[2] += [50,60]
# print(t)
'''不要把可变对象放在元组里
增量赋值不是一个原子操作'''
# list.sort() 原地排序 函数的返回值是None
# sorted(sequence) 返回一个列表
# 两个参数 key 和 reverse
# key = 函数名 排序的依据
# reverse = True/ False
import bisect
import sys
import random
# 用bisect来管理以排序的序列
# bisect.bisect()
# bisect.insort()
# HAYSTACK = [1,4,5,6,8,12,15,20,21,23,23,26,29,30]
# NEEDLES = [0,1,2,55,8,10,22,23,29,30,31]
# ROW_FMT = '{0:2d}@{1:2d} {2}{1:<2d}'
# def demo(bisect_fn):
# for needle in reversed(NEEDLES):
# pos = bisect_fn(HAYSTACK,needle)
# offset = pos * " |"
# print(ROW_FMT.format(needle,pos,offset))
# if __name__ == '__main__':
# if sys.argv[-1] == 'left':
# bisect_fn = bisect.bisect_left
# else:
# bisect_fn = bisect.bisect
# print('DEMO:',bisect_fn.__name__)
# print('haystack->'," ".join('%2d'%n for n in HAYSTACK))
# demo(bisect_fn)
# 根据一个分数找到对应的成绩
"""def grade(score,breakpoint = [60,70,80,90],grades = 'FDCBA'):
return grades[i]
i = bisect.bisect(breakpoint,score)
lis = [grade(score) for score in [33,45,65,73,83,99,55,77,90]]
print(lis)
"""
# 用bisect.insort插入新元素
# insort(seq,item) 把item插入到seq中 并保持seq有序
"""
SIZE = 7
random.seed(1729)
my_list = []
for i in range(SIZE):
new_item = random.randrange(SIZE*2)
bisect.insort(my_list,new_item)
print('%2d->'%new_item,my_list)"""
# 列表的替代array.array
# 除了支持.pop,.insert,.extend外还支持从文件读取和存入文件.tofile,.frombytes
# array.array('b')
# 第一个参数:'b' 类型符 8位正数 -128~127
# 'd' 双精度浮点型
from array import array
from random import random
# 一个浮点型数组的创建\存入文件\从文件读取
"""
floats = array('d',(random() for i in range(10**7)))
print(floats[-1])
fp = open('floats.bin','wb')
floats.tofile(fp)
fp.close()
floats2 = array('d')
fp = open('floats.bin','rb')
floats2.fromfile(fp,10**7) # 第二个参数代表读取的数量
fp.close()
print(floats2[-1])
print(floats2 == floats)"""
# 列表的替代 memoryview(内存视图)
# 在不复制内容的情况下操作同一个数组的不同切片
# 通过改变数组中的一个字节来更新数组里某个元素的值
numbers = array('h',[-2,-1,0,1,2])
memv = memoryview(numbers)
print(len(memv))
print(memv[0])
memv_oct = memv.cast('B') # 转化为无符号类型
print(memv)
print(memv_oct)
print(memv_oct.tolist()) # 以列表的形式查看memv_oct
memv_oct[5] = 4 # 把位于5的字节赋值为4
print(numbers)
numpy的基本操作
import numpy
a = numpy.arange(12)
print(a)
print(type(a))
print(a.shape) # 形状
a.shape = 3,4
print(a)
print(a[2])
print(a[2,1])
print(a[:,1])
b = a.transpose() # 转置
print(b)
# 双向队列 collections.deque
from collections import deque
dq = deque(range(10),maxlen=10) # maxlen最大长度
print(dq)
dq.rotate(3) # 最右边的3个元素移动到队列的左边
print(dq)
dq.rotate(-4) # 移动到右边
print(dq)
dq.appendleft(-1) # 队列满时,头部添加 尾部会被删除
print(dq)
dq.extend([11,22,33])
print(dq)
dq.extendleft([10,20,30])
print(dq)