推导式
推导式是一种用一行代码创建列表、字典、集合或生成器的简洁方式,本质是"带条件的循环 + 表达式"。【类似于语法糖的概念】
列表推导式
py
names = ['Bob','Tom','alice','Jerry','Wendy','Smith']
new_names = [name.upper()for name in names if len(name)>3]
print(new_names)
# ['ALICE', 'JERRY', 'WENDY', 'SMITH']
这段代码中是定义了一个叫 names 的列表,然后通过推导式操作 以 name 循环 names,并获取 name 中大于 3 的项,最后将得到的结果进行大写转换。
推导式的运行逻辑一般是
[表达式 for 变量 in 列表][表达式 for 变量 in 列表 if 条件]
字典推导式
py
listdemo = ['Google','Runoob', 'Taobao']
# 将列表中各字符串值为键,各字符串的长度为值,组成键值对
newdict = {key:len(key) for key in listdemo}
# newdict {'Google': 6, 'Runoob': 6, 'Taobao': 6}
所以字典推导式一般是:
{key: value for key in 列表}
注意这里可以先看 for in 部分,for in部分获取到的是 key。再看前面 key: 之后的部分,获得是 value,最后通过循环组合成一个完整的字典。
py
dic = {x: x**2 for x in (2, 4, 6)}
# dic的结果为{2: 4, 4: 16, 6: 36}
集合推导式
py
setnew = {i**2 for i in (1,2,3)}
setnew {1, 4, 9}
这里也是先看后半部分,循环 i 得到每一个数据,即 1、2、3。然后将 i 进行幂运算,得到的结果为1、4、9。因为处在 Set 中有需要剔除重复的,所以结果为 {1, 4. 9}。
元组推导式
py
a = (x for x in range(1,10))
# a <generator object <genexpr> at 0x7faf6ee20a50>
# 返回的是生成器对象
tuple(a)
# 使用 tuple() 函数,可以直接将生成器对象转换成元组 (1, 2, 3, 4, 5, 6, 7, 8, 9)
与列表推导式效果基本相同,唯一的区别在于元组本身的不可变特性。
迭代器
迭代器是一个可以记住遍历位置的对象,它实现了 iter () 和 next() 方法,让你能"一个一个地"取出数据,而不需要一次性加载所有数据到内存。
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
字符串,列表或元组对象都可用于创建迭代器:
py
# 列表
list=[1,2,3,4]
it = iter(list)
# 创建迭代器对象
print (next(it))
# 输出迭代器的下一个元素,这里会输出 1
print (next(it))
# 输出迭代器的下一个元素,这里会输出 2
# 也可以使用 for 循环,无需使用 next 方法
list=[1,2,3,4]
it = iter(list)
# 创建迭代器对象
for x in it: print (x, end=" ")
# 或者使用 while 循环
import sys
# 引入 sys 模块
list=[1,2,3,4]
it = iter(list)
# 创建迭代器对象
while True:
try:
print (next(it))
except StopIteration:
sys.exit()
注意 :使用 iter() 创建的迭代器 并不是"转换成一种类似于列表的形式",而是一个完全不同的对象类型------它没有索引、不能随机访问、不能重复遍历,只能单向、逐个、一次性地获取元素。
生成器
Python可以使用 yield 创建生成器。生成器是一种特殊的函数,可以在迭代的过程中逐步产生值。
python
def countDown(n):
while n > 0:
yield n
n -= 1
genertor = countDown(5)
print(next(genertor))
print(next(genertor))
print(next(genertor))
print('---分割线---')
for i in genertor:
print(i)
"""
5
4
3
---分割线---
2
1
"""
with资源释放
在需要释放资源的操作中,忘记释放往往是最关键的问题。
所以Python中增加了 with 关键字主动释放资源。
py
# 传统方法
file = open('example.txt', r)
try:
content = file.read()
finally:
file.close()
# with关键字【这里会在使用完文件资源以后自动释放】
with open('example.txt', r) as file
content = file.read()
print(content)
with可以进行非常多的资源操作:文件、线程锁、数据库等等。
函数
Python中的函数有以下规则:
- 函数代码块以
def关键词开头,后接函数标识符名称和圆括号 ()。 - 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性地使用文档字符串---用于存放函数说明。
- 函数内容以冒号 : 起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方,不带表达式的
return相当于返回None。'
py
def hello() :
print("Hello World!")
hello()
Python参数中可以使用传统的默认参数的方法,给参数赋默认值。
可以在最后一个参数处增加 * 符号,这些未命名的参数会以元组的方式被接收。
py
def hello(num, *vartuple):
print(num)
for i in vartuple:
print(i)
hello('wang', 'ha', 'ha', 'ha')
还可以在最后一个参数处增加 ** 符号,参数会以字典的形式被接收。
py
def hello(num, **vardict):
print(num)
print(vardict)
hello('wang', a = 2, b = 3) # 打印结果 wang {a:2, b:3}
在声明函数的时候,* 符号可以单独出现,代表仅限关键字参数。
也就是说在 * 符号以后的所有参数都必须以关键字的形式传入,不能再使用位置传参。
py
def printName(a, b, *, c):
print(a, b, c)
printName('Tom', 'Jerry', c='coke')
匿名函数
匿名函数可以简单理解为没有函数名的函数,定义匿名函数使用 lambda 关键字。
注意 :lambda 表达式只能写一行,它是一个 表达式。【实际开发使用并不算多。】
lambda 参数: 表达式
py
f = lambda x: x * 2
g = lambda x, y: x if x > y else y
# 条件表达式是可以的 h = lambda s: s.strip().upper() # 方法链也是表达式
强制位置参数
Python 3.8 新增一个函数形参的 / 符号,代表此符号之前的形参必须采用 位置参数 的形式,不能采用关键字传参。
py
def f(a, b, /, c, d, *, e, f):
print(a, b, c, d, e, f)
f(10, 20, 30, d=40, e=50, f=60)
# 正确 f(10, b=20, c=30, d=40, e=50, f=60)
# b 不能使用关键字参数的形式 f(10, 20, 30, 40, 50, f=60) # e 必须使用关键字参数的形式