54.推导式创建序列
推导式是从一个或者多个迭代器
快速创建序列
的一种方法。它可以将循环和条件判断结合
, 从而避免冗长的代码
。推导式是典型的Python 风格,会使用它代表你已经超过Python初 学者的水平。
文章目录
列表推导式
列表推导式生成列表对象,语法如下:
[表达式 for item in 可迭代对象 ]
或者:
[表达式 for item in 可迭代对象 if 条件判断]
>>> [x for x in range(1,5)]
[1, 2, 3, 4]
>>> [x*2 for x in range(1,5)]
[2, 4, 6, 8]
>>> [x*2 for x in range(1,20) if x%5==0 ]
[10, 20, 30]
>>> [a for a in "abcdefg"]
['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> cells = [(row,col) for row in range(1,10) for col in range(1,10)] #可以使用两 个循环
>>> for cell in cells:
print(cell)
字典推导式
字典的推导式生成字典对象,格式如下:
{key_expression : value_expression for 表达式 in 可迭代对象}
类似于列表推导式,字典推导也可以增加 if条件判断、多个 for 循环。
统计文本中字符出现的次数:
推导式代码
my_text = "i love you, i love python, i love onepis"
char_count = {c: my_text.count(c) for c in my_text}
print(char_count)
普通代码
# 使用普通的循环实现上面字典推导式实现的字符出现次数的统计
char_count = {}
my_text = "i love you, i love python, i love onepis"
for c in my_text:
my_text.count(c)
char_count[c] = my_text.count(c)
print(char_count)
# 输出:
{'i': 4, ' ': 8, 'l': 3, 'o': 6, 'v': 3, 'e': 4, 'y': 2, 'u': 1, ',': 2, 'p': 2, 't': 1, 'h': 1, 'n': 2, 's': 1}
集合推导式
集合推导式生成集合,和列表推导式的语法格式类似:
{表达式 for item in 可迭代对象 }
或者:
{表达式 for item in 可迭代对象 if 条件判断}
# 集合推导式
# 本质上集合还是字典,只是里面全是key 没有value,特点是不可重复
b = {x for x in range(1, 100) if x % 9 == 0}
print(b)
生成器推导式(生成元组)
很多同学可能会问:“都有推导式,元组有没有?”,能不能用小括号呢?
>>> (x for x in range(1,100) if x%9==0)
<generator object <genexpr> at 0x0000000002BD3048>
gnt = (x for x in range(4))
# print(tuple(gnt))
for x in gnt: # gnt是生成器对象,生成器是可迭代的对象,只能使用一次
print(x, end=",") # 这里是用for循环去迭代遍历 生成器.输出 打印
print(tuple(gnt)) # 第二次输出打印所以 没有数据线了,只有()
我们发现提示的是“一个生成器对象”。显然,元组是没有推导式的。
一个生成器只能运行一次。第一次迭代可以得到数据,第二次迭代发现数据已经没有了。
嵌套推导式
1 列表套列表
# 推导式
some_tuple = [(1, 2, 3), (4, 5, 6), (7, 8, 9)]
list1 = [[x for x in tup] for tup in some_tuple]
print(list1)
# 输出
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print('***********************')
# 普通循环
list2 = []
for tup in some_tuple:
list2 .append(list(tup))
# 不过从循环次数来说 普通的 循环
# 特别是涉及到操作 元素的 比如 append 我感觉 还是普通的好。
# 因为循环次数减少了。
# 当然也和你的 需求相关。
# 具体问题具体分析
print(list2)
2 一个列表套两个 for 循环
2.1 有点像 product
函数 的感觉
[(x, y) for x in range(5) for y in range(5)]
# 输出
[(0, 0),
(0, 1),
(0, 2),
(0, 3),
(0, 4),
(1, 0),
(1, 1),
(1, 2),
(1, 3),
(1, 4),
(2, 0),
(2, 1),
(2, 2),
(2, 3),
(2, 4),
(3, 0),
(3, 1),
(3, 2),
(3, 3),
(3, 4),
(4, 0),
(4, 1),
(4, 2),
(4, 3),
(4, 4)]
2.2 在列表推导式中 序列解包
a = ['I lobe u\n', '123\n', 'dad\n']
b = enumerate(a)
# 枚举,用元组包含起来,做一个索引 enumerate方法
# 前面讲过的 返回一个元组 。
# 忘记的朋友 可以去看我的博客 38_序列解包
print("a -> ",a)
print("list b -> ",list(b))
# 在后面 添加序号 #+数字 的形式
c = [temp.rstrip()+' #' + str(index) for index, temp in enumerate(a)]
# rstrip去掉右边空白符号
# index,temp 看做一 块内容. 其实 就是 解包 解出来两个元素
# 用两个变量 来接收
print("c-> ",c)
# 输出
a -> ['I lobe u\n', '123\n', 'dad\n']
list b -> [(0, 'I lobe u\n'), (1, '123\n'), (2, 'dad\n')]
c-> ['I lobe u #0', '123 #1', 'dad #2']
3 批量创建文件
# 批量创建文件
import os
path = r'C:\Users\bai\Desktop\test\2'
os.chdir(path) # 改变当前文件夹
a = range(10)
b = []
[b.append(str(z)) for z in a] # 把列表a里面的 int数字 转换为 字符串装到列表b
files = ['test (' + y + ').txt' for y in b]
for x in files:
with open(x, 'w')as f: # w 是 write 写的意思。 写模式。 后面会详细讲解 io 输入输出的
f.write('')
5 加判断的推导式
# 列出工作目录下的所有的.py文件,并且输出文件名
# 普通代码
path = os.getcwd() # 返回工作目录以及文件 get current directory 的 简写
# 获取 当前 工作目录的意思
file_list = os.listdir(path) # 列出子目录、子文件
for filename in file_list:
if filename.endswith('py'):
# 文件以 什么结尾 里面 写py 就是 以 py 结尾的意思
# endswith 返回的 是一个bool 值
# 用于判断 是否 以 py 结尾
print(filename)
print('***********************')
# 用推导式实现
file_list2 = [filename for filename in os.listdir(
path) if filename.endswith('py')]
for f in file_list2:
print(f, end='\t')
'''
一些简单的 计算机常识
print(os.curdir) # 返回一个点 . 代表当前 文件夹,两个点 .. 是上级目录
print(os.pardir) # 返回上级目录
print(os.name) # 返回操作系统名称
'''