python day17:迭代器,生成器,time和random模块

列表生成式

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差不多,除了取值范围是左开右闭区间 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值