列表生成式
a=[x for x in range(10)]
有人说直接a=range(10)不就好了嘛,何必要弄一个列表生成式你
a=[x**2 for x in range(10)]
def f(n):
return n**2
a=[f(x) for x in range(10)]
这便是列表生成式的简便之处
生成器
a=(x for x in range(10))
print(a)
如果根据列表生成器的思路,打印出来的应该是一个一到十的元组
然而结果如下
<generator object <genexpr> at 0x0000022368C08740>
相比于列表占内存,调用的时候要从内存里来拿,生成器就像一个厨师,你不吃的时候他不做菜,要吃的时候才做好了端上来。
想要拿出生成器的内容,需要函数next
a=(x for x in range(10))
print(next(a))
输出结果为0
再next一次输出结果为1
以此类推
注意,在python2中是用a.next()方法调用的
如果超出了range的范围,会报错提示超出迭代范围
我们发现生成器就是一种迭代器,则也可以用迭代器的常用方法拿取内容
a=(x for x in range(10))
for i in a:
print(i)
生成器还可以用yield方法生成
def gene():
yield 1
gene()就是一个生成器
和一般的函数不同,我们说函数f是一个单独的变量,加上括号变成f()代表调用函数f,而gene()自己本身就是生成器
在每次用next调用迭代器时,指针会停在上一次调用yield的位置,因此
def gene():
a=1
yield a
a+=1
yield a
c=gene()
print(next(c))
print(next(c))
输出结果为
1
2
但是若不把生成器赋给变量而直接next引用
def gene():
a=1
yield a
a+=1
yield a
print(next(gene()))
print(next(gene()))
输出结果为
1
1
因为直接引用作为函数的生成器在每次调用都会从头开始执行,这一情况要注意!
yield在某些尺度上可以说是保存了命令所在的状态,例如
def gene():
a=1
yield a
a+=1
print('status')
yield a
c=gene()
print(next(c))
print(next(c))
输出结果为
1
status
2
说明next一次函数就执行一次到下一个yield的进度
send 方法
sand除了和next一样一个一个调出生成器内容的功能外,还可以给yield 的变量传值
def gene():
a=1
c=yield a
print(c)
a+=1
yield a
g=gene()
print(g.send(None))
g.send(10)
send内必须跟一个内容,不然会报错,g.send(None)等同于next(g)
并且在生成器第一次迭代时send内只能加None,不然会报错
之后每一次send()都会把send的内容赋值给前一次的yield
则可以知道上段代码输出结果为
1
2
迭代器
生成器都是迭代器,迭代器不都是生成器
什么是迭代器?
满足两个条件(迭代器协议):1.有iter方法 2.有next方法
a=[1,2,3,4]
d=iter(a)
iter方法返回一个迭代器对象
例如list,tuple,dict,string这些可迭代对象都可以生成迭代器
对于for循环在处理数据的过程中:
1 调用可迭代对象的iter方法返回一个迭代对象
2 不断调用迭代器对象的next方法
3 处理StopIteration
可以发现for循环都是把输入的可迭代对象处理成迭代器再进行循环next
isinstance的用法
isinstance(数据对象,可迭代类型)
用于判断数据对象是否为相应可迭代类型
例如
print(isinstance([1,2,3],list))
输出结果为True
也可以判断数据对象是否为迭代器
from collections import Iterator,Iterable
def a():
yield 1
print(isinstance(a(),Iterable))
time 模块
import time
time.time
print(time.time())
输出以时间戳表示的当前时间(时间戳是以秒为单位,当前时间到unix诞生那年的时间差)
time.clock
print(time.clock())
用于返回CPU时间,以此来计算程序的耗时,python3.8之后删除了time.clock(),用time.perf_counter()代替
time.gmtime
print(time.gmtime())
结构化时间,输出结果为世界标准时间(格林尼治时间)
time.struct_time(tm_year=2023, tm_mon=2, tm_mday=14, tm_hour=6, tm_min=55, tm_sec=40, tm_wday=1, tm_yday=45, tm_isdst=0)
time.localtime
本地时间,输出的结构和gmtime一样,时间是电脑设定所在时区的时间
time.strftime
print(time.strftime('%Y:%m:%d',time.localtime()))
输出结果
2023:02:14
且结果数据类型为str
strftime目的就是将结构化时间格式化成字符串时间
%Y Year with century as a decimal number.
%m Month as a decimal number [01,12].
%d Day of the month as a decimal number [01,31].
%H Hour (24-hour clock) as a decimal number [00,23].
%M Minute as a decimal number [00,59].
%S Second as a decimal number [00,61].
%z Time zone offset fom UTC.
%a Locale's abbreviated weekday name.
%A Locale's full weekday name.
%b Locale's abbreviated month name.
%B Locale's full month name.
%c Locale's appropriate date and time representation.
%I Hour (12-hour clock) as a decimal number [01,12].
%p Locale's equivalent of either AM or PM.
time.strptime
和strftime相反,strptime是将字符串时间转化成结构化时间
print(time.strptime('2000-01-01','%Y-%m-%d'))
time.ctime
把时间戳转换成已被定义号的字符串时间
print(time.ctime(200))
输出结果为
Thu Jan 1 08:03:20 1970
time.mktime
print(time.mktime(time.localtime()))
把结构化时间转化为时间戳
random模块
import random
random.random
print(random.random())
随机生成一个0-1的一位小数
random.randint
print(random.randint(1,8))
自己设定范围,随机生成一个范围(注意是两边都是闭区间)内的整数
random.choice
print(random.choice('hello'))
内部可放任意一种可迭代对象,然后随机选出一个元素
random.shuffle
x=[1,2,3,4,2]
random.shuffle(x)
print(x)
洗牌器,把原本列表(注意只有列表)打乱 ,注意random.shuffle()自身没有返回值,所以出现例如x=random.shuffle([2,3,4])这样只能得到一个None值
random.sample
print(random.sample('hello'),3)
从一个可迭代对象中随机拿出特定数目的元素
random.randrange()
print(random.randrange(1,8))
其实和random.randint差不多,除了取值范围是左开右闭区间