python基础学习-列表解析式与生成器表达式
标准库 datetime
datetime模块
- 对日期、时间、时间戳的处理
- datetime类
- 类方法
- today() 返回本地时区当前时间的datetime对象
- now(tz=None) 返回当前时间的datetime对象,时间到微秒,tz表示时区,如果tz为None,返回和today()一样。
- utcnow()没有时区的当前时间
- fromtimestamp(timestamp,tz=None) 从一个时间戳返回一个datetime对象
- datetime对象
- timestamp() 返回一个到微秒的时间戳
- 时间戳:格林威治时间1970年1月1日0点到现在的秒数
- timestamp() 返回一个到微秒的时间戳
- 类方法
datetime对象
- 构造方法 datetime.datetime(2016,12,6,16,29,43,79043)
- year、month、day、hour、minute、second、microsecond,取datetime对象的年月日时分秒及微秒
- weekday() 返回星期的天,周一为0,周日为6
- isoweekday() 返回星期的天,周一为1,周日为7
- date() 返回日期date对象
- time() 返回时间time对象
- replace() 修改并返回新的时间
- isocalendar() 返回一个三元组(年,周数,周的天)
日期格式化
类方法 strptime(date_string, format),返回datetime对象
对象方法 strftime(format),返回字符串
字符串format函数格式化
import datetime
dt = datetime.datetime.strptime(“21/11/06 16:30”,”%d %m %y %H:%M”)
print(dt.strftime(“%Y-%m-%d %H:%M:%S”))
print(“{0:%Y}/{0:%m}/{0:%d} {0:%H}::{0:%M}::{0:%S}”.format(dt))
timedelta对象
- datetime2 = datetime1 + timedelta
- datetime2 = datetime1 - timedelta
- timedelta = datetime1 - datetime2
- 构造方法
- datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0,minutes=0, hours=0, weeks=0)
- year = datetime.timedelta(days=365)
- total_seconds() 返回时间差的总秒数
标准库time
- time
- time.sleep(secs) 将调用线程挂起指定的秒数
练习
1 | import datetime |
列表解析
- 举例
- 生成一个列表,元素0~9,对每一个元素自增1后求平方返回新列表
1 | # 生成一个0-9的列表,之后将每个元素加1,再求平方返回一个新列表 |
列表解析List Comprehension
- 语法
- [返回值 for 元素 in 可迭代对象 if 条件]
- 使用中括号[],内部是for循环,if条件语句可选
- 返回一个新的列表
- 列表解析式是一种语法糖
- 编译器会优化,不会因为简写而影响效率,反而因优化提高了效率
- 减少程序员工作量,减少出错
- 简化了代码,但可读性增强
- 语法糖(Syntactic sugar)是由英国计算机科学家彼得·兰丁发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能没有影响,但是更方便程序员使用。语法糖让程序更加简洁,有更高的可读性。糖在不改变其所在位置的语法结构的前提下,实现了运行时等价。
- 举例
- 获取10以内的偶数,比较执行效率
1 | even = [] |
- 思考
有这样的赋值语句newlist = [print(i) for i in range(10)],请问newlist的元素打印出来是什么?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15newlist = [print(i) for i in range(10)]
print(newlist)
输出:
0
1
2
3
4
5
6
7
8
9
[None, None, None, None, None, None, None, None, None, None]
# 可以看到,标准输出的是None的列表。这是因为必须要把函数执行完了用print(i)的返回值来填充列表,而print(i)的返回值是None。所以这里应该用newlist = [i for i in range(10)]获取20以内的偶数,如果数是3的倍数也打印[i for i in range(20) if i%2==0 elif i%3==0] 行
吗?
1 | [i for i in range(20) if i%2==0 elif i%3==0] |
列表解析进阶
1 | [expr for item in iterable if cond1 if cond2] |
列表解析练习
1 | 练习(要求使用列表解析式完成) |
生成器表达式 Generator expression
- 语法
- (返回值 for 元素 in 可迭代对象 if 条件)
- 列表解析式的中括号换成小括号就行了
- 返回一个生成器
- 和列表解析式的区别
- 生成器表达式是按需计算(或称惰性求值、延迟计算),需要的时候才计算值
- 列表解析式是立即返回值
- 生成器
- 可迭代对象
- 迭代器
生成器表达式**
1 | 举例: |
生成器表达式
1 | 习题1 |
- 和列表解析式的对比
- 计算方式
- 生成器表达式延迟计算,列表解析式立即计算
- 内存占用
- 单从返回值本身来说,生成器表达式省内存,列表解析式返回新的列表
- 生成器没有数据,内存占用极少,但是使用的时候,虽然一个个返回数据,但是合起来占用的内存也差不多
- 列表解析式构造新的列表需要占用内存
- 计算速度
- 单看计算时间看,生成器表达式耗时非常短,列表解析式耗时长
- 但是生成器本身并没有返回任何值,只返回了一个生成器对象
- 列表解析式构造并返回了一个新的列表
- 计算方式
集合解析式
- 语法
- {返回值 for 元素 in 可迭代对象 if 条件}
- 列表解析式的中括号换成大括号{}就行了
- 立即返回一个集合
- 用法
- {(x,x+1) for x in range(10)}
- {[x] for x in range(10)}
字典解析式
- 语法
- {返回值 for 元素 in 可迭代对象 if 条件}
- 列表解析式的中括号换成大括号{}就行了
- 使用key:value形式
- 立即返回一个字典
- 用法
- {x:(x,x+1) for x in range(10)}
- {x:[x,x+1] for x in range(10)}
- {(x,):[x,x+1] for x in range(10)}
- {[x]:[x,x+1] for x in range(10)} #
- {chr(0x41+x):x**2 for x in range(10)}
- {str(x):y for x in range(3) for y in range(4)} # 输出多少个元素?
- 用法
1 | 用法 |
总结
- Python2 引入列表解析式
- Python2.4 引入生成器表达式
- Python3 引入集合、字典解析式,并迁移到了2.7
- 一般来说,应该多应用解析式,简短、高效
- 如果一个解析式非常复杂,难以读懂,要考虑拆解成for循环
- 生成器和迭代器是不同的对象,但都是可迭代对象
- 迭代器一定是一个可迭代对象,但是可迭代对象未必是迭代器
- 生成器对象一定是一个迭代器,但是迭代器未必是生成器对象
- 从返回值本身来说,生成器表达式省内存,返回的是一个生成器对象
python基础学习-列表解析式与生成器表达式
https://python0.netlify.app/2019/10/10/python基础学习-列表解析式与生成器表达式/