第2章序列构成的数组

示例2.1/2.2/2.3 把一个字符串变成Unicode码位的列表

普通方法

symbols='!@#$%^'
codes=[]
for symbol in symbols:#使用append()方法向空列表添加元素
    codes.append(ord(symbol))
print(codes)

输出结果:

在这里插入图片描述

使用列表推导的方法

symbols='!@#$%^'
codes=[ord(symbol)for symbol in symbols]#列表推导的固定写法,看起来是不是更简洁?
print(codes)

输出结果:
在这里插入图片描述

使用filter和map创建

alphabet='abcdefghijklmnopqrstuvwxyz'
#beyond_ascii=[ord(s) for s in alphabet if ord(s)<100]
beyond_ascii=list(filter(lambda s:s<100,map(ord,alphabet)))#map根据指定函数做映射,返回迭代器。fillter用于过滤序列
print(beyond_ascii)

输出结果:
在这里插入图片描述

示例2.4 使用列表推导计算笛卡尔积

注:笛卡尔积是一个列表,列表里的元素是由输入的可迭代类型的元素对构成的元组,因此笛卡尔积列表的长度等于输入各变量长度的乘积。

colors=['black','white']
sizes=['S','M','L']
tshits=[(color,size) for color in colors \
                        for size in sizes]#\是续行符,在[],(),{}中的换行可以省略
print(tshits)#得到的结果先以颜色排列,再以尺码排列

tshits2=[(size,color) for size in sizes
                       for color in colors]
print(tshits2)#得到的结果先以尺码排列,再以颜色排列

输出结果:
在这里插入图片描述

示例2.5 用生成器表达式初始化元组和数组

生成器类似列表推导

import array
alphabet='abcdefghijklmnopqrstuvwxyz'
t=tuple(ord(s) for s in alphabet)
print(t)
a=array.array('I',(ord(s) for s in alphabet))
print(a)

输出结果:
在这里插入图片描述

示例2.6 用生成器表达式计算笛卡尔积

colors=['black','white']
sizes=['S','M','L']
for tshirt in ('%s %s' % (c,s) for c in colors for s in sizes):#生成器表达式只会逐个产生元素
    print(tshirt)

输出结果:
在这里插入图片描述

示例2.7 把元组用作记录

lax_coordinates=(33.9425,-118.408056)
city,year,pop,chg,area=('Tokyo',2003,32450,0.66,8014)
traveler_ids=[('USA','31195855'),('BRA','CE342567'),('ESP','XDA205856')]
for passport in sorted(traveler_ids):#在迭代时,passport变量被绑定到每一个元组上
    print('%s/%s' %passport)# %格式运算符能被匹配到对应的元组元素上

for contry,_ in traveler_ids:#for循环分别提取元组里的元素,叫做拆包。元组中第二个元素没有使用,可以使用占位符‘_’
    print(contry)

输出结果:
在这里插入图片描述

示例2.8 嵌套元组拆包

metro_areas=[
    ('Tokyo','JP',36.993,(35.689722,139.691667)),#每个元组有4个元素,其中最后一个是一对坐标
    ('Delhi NCR','IN',21.935,(28.613889,77.208889)),
    ('Mexico City','MX',20.142,(19.433333,-99.13333)),
    ('New York-Newark','US',20.104,(40.808611,-74.020386)),
    ('Sao Paulo','BR',19.649,(-23.547778,-46.635833))
]
print('{:15} | {:^9} | {:^9}'.format('','lat.','long.'))
fmt='{:15} | {:^9} | {:^9}'
for name,cc,pop,(lat,lon) in metro_areas:#可以把元组最后一个元素拆包到由变量构成的元组中
    if lon<=0:#限制输出西半球的城市
        print(fmt.format(name,lat,lon))

输出结果:
在这里插入图片描述

示例2.9/2.10 具名元组

具名元组可以用来构建一个带字段名的元组和一个有名字的类

from collections import namedtuple
City=namedtuple('City','name country population coordinates')#具名元组有两个参数,一个是类名,另一个是类的各个字段的名字。
tokyo=City('Tokyo','JP',36.933,(35.689722,139.691667))
print(tokyo)
print(tokyo.population)#可以通过字段名或者位置来获取某个字段的信息
print(tokyo[3])
print(City._fields)#_fields属性是一个包含这个类所有字段名称的元组
LatLong=namedtuple('LatLong','lat long')
delhi_data=('Delhi NCR','IN',21.935,LatLong(28.613889,77.208889))
delhi=City._make(delhi_data)#通过接受一个可迭代对象来生成这个类的一个实例,它的作用跟City(*delhi_data)一样
print(delhi._asdict())#把具名元组以collections.OrderedDict的形式返回

输出结果:
在这里插入图片描述

示例2.11 对对象进行切片

用slice对seq[start:stop:step]进行切片,可以给切片命名

salarys='''
姓名   基础工资 绩效工资 出勤   工龄工资 五险一金 扣税   实发
老江   8000 6000 1000 200  -1200-400  13600
老谢   7800 6000 1000 200  -1200-400  13400
瓜皮昊  7600 6000 1000 200  -1200-400  13200
冬瓜李呢 7000 6000 1000 200  -1200-400  12600
'''
name=slice(0,5)
base_sal=slice(5,10)
bonus=slice(10,15)
commutting=slice(15,20)
time_bonus=slice(20,25)
ensurance=slice(25,30)
tax=slice(30,35)
totle=slice(35,None)
line_items=salarys.split('\n')[2:]
for item in line_items:
    print(item[name],item[totle])

输出结果:
在这里插入图片描述

示例2.12/2.13 建立列表组成的列表

模拟3*3的方块矩阵,创建一个包含3个列表的列表

#示例2.12
board=[['_']*3for i in range(3)]#建立一个包含3个列表的列表,被包含的三个列表各自有三个元素。
print(board)
board[1][2]='x'#把第一行第二列元素标记为x
print(board)

输出结果:
在这里插入图片描述

含有3个指向同一对象的引用的列表是毫无用处的

#示例2.13
weird__board=[['_']*3]*3#外面的列表其实包含三个指向同一个列表的引用
print(weird__board)
weird__board[1][2]='x'#一旦我们试图标记某个元素,就立马暴露了列表内三个引用指向同一对象的事实
print(weird__board)

输出结果:

在这里插入图片描述

示例2.13犯的错误本质和下列代码一致

row=['_']*3
borad=[]
for i in range(3):
    borad.append(row)#向空列表加入了同一个行对象(row)三次到游戏板(board)
print(borad)
borad[1][2]='x'
print(borad)

输出结果:
在这里插入图片描述

相反,示例2.12中的做法与下列等同

board=[]
for i in range(3):
    row=['_']*3#每次循环都新建了一个列表,作为新的一行(row)加入到游戏板(board)
    board.append(row)
print(board)
board[0][0]='a'
print(board)

输出结果:
在这里插入图片描述

bisect二分查找模块

示例2.17 在有序序列中用bisect查找某个元素的插入位置

import bisect#bisect模块主要包含两个主要函数,bisect和insort,这两个函数都利用二分查找算法来在有序序列中查找或插入元素
import sys#sys是一个与当前程序运行之外的系统环境打交道的模块
HAYSTACK=[1,4,5,6,8,12,15,20,21,23,23,26,29,30]
NEEDLES=[0,1,2,5,8,10,22,23,29,30,31]
ROW_FMT='{0:2d} @ {1:2d}    {2}{0:<2d}'
def demo(bisect_fn):
    for needle in reversed(NEEDLES):
        position=bisect_fn(HAYSTACK,needle)#用特定的bisect函数来计算元素应该出现的位置
        offset=position *'  |'#利用该位置算出需要几个分隔符号
        print(ROW_FMT.format(needle,position,offset))#按格式打印元素和应该出现的位置
if __name__=='__main__':#如果当前模块时被直接执行,__name__的值就是__main__,条件判断的结果为True,“if __name__=='__main__':”下面的代码块就会被执行。
    if sys.argv[-1]=='left':#选择是bisect_left函数还是bisect_right函数
        biset_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)

输出结果:
在这里插入图片描述

bisect函数是bisect_right函数的别名,它还有一个姊妹函数叫bisect_left。区别在于遇到相同值时是左插入还是右插入。

示例2.18 根据一个分数,找到他所对应的成绩

import bisect
def grade(score,breakpoints=[60,70,80,90],grades='FDCBA'):
    i=bisect.bisect(breakpoints,score)#获得插入位置的index
    return grades[i]
l=[grade(score) for score in [33,99,77,70,89,90,100]]
print(l)

输出结果:
*['F', 'A', 'C', 'C', 'B', 'A', 'A']*

示例2.19 insort可以保持有序序列的顺序插入

import bisect
import random
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)

输出结果:
在这里插入图片描述

某些情况下可以替换列表的数据类型

示例2.20 一个浮点数类型的创建、存入文件和从文件中读取的过程

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)#把1000万个浮点数从二进制文件中读取出来
fp.close()
print(floats2[-1])#查看新数组的最后一个元素
print(floats2==floats)#检查两个数组是否完全一样

输出结果:
在这里插入图片描述

示例2.21 (内存视图)通过改变数组中的一个字节来更新数组中某个元素的值

import array
numbers=array.array('h',[-2,-1,0,1,2])
memv=memoryview(numbers)#利用含有5个短整型有符号整数(类型码'h')的数组创建一个memoryview
print(len(memv))
print(memv[0])#memv中的5个元素与数组中的没有区别
memv_oct=memv.cast('B')#创建一个memv_oct,把memv里的内容转换成无符号字符('B'类型)
print(memv_oct.tolist())#以列表形式查看memv_oct的内容
memv_oct[5]=4#把位于位置5的字节赋值成4
print(numbers)

输出结果:

在这里插入图片描述

示例2.23 使用双向队列

from collections import deque
dq=deque(range(10),maxlen=10)#maxlen是一个可选参数,代表这个队列可以容纳的元素的数量,一旦设定不能更改
print(dq)
dq.rotate(3)#队列的旋转操作接收一个参数n,当n>0时,队列最右边的n个元素会被移到队列的左边。当n<0时,最左边的n个元素会被移到右边
print(dq)
dq.rotate(-4)
print(dq)
dq.appendleft(-1)#对已满的队列进行头添加时,尾部的元素会被删除
print(dq)
dq.extend([11,22,33])
print(dq)
dq.extendleft([10,20,30,40])#extendleft(iter)方法会把迭代器里的元素逐个添加到双向队列的左边,因此迭代器里的元素会逆序的出现在队列中
print(dq)

输出结果:

在这里插入图片描述
双向队列deque常用函数
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值