切片(Slice)
切片:截取
list
、tuple
或者str
的元素
L = [0, 1, 2, 3, 4, 5]
print(L[: 3]) # [0, 1, 2]
print(L[0:3]) # [0, 1, 2]
print(L[0:]) # [0, 1, 2, 3, 4, 5]
print(L[:]) # [0, 1, 2, 3, 4, 5]
print(L[2:4]) # [2, 3]
print(L[::2]) # [0, 2, 4] 指定步长
print(L[-3:]) # [3, 4, 5]
print(L[:-1]) # [0, 1, 2, 3, 4]
print(L[-4:-1]) # [2, 3, 4]
实现一个trim()函数,去除字符串首尾的空格(不使用
str
的strip()
函数)
def my_trim(s):
while s and s[0] == ' ': # 去除开头的空格
s = s[1:]
while s and s[-1] == ' ': # 去除结尾的空格
s = s[:-1]
return s
迭代(Iteration)
在Python中,迭代是通过
for ... in
来完成的
L = list(range(10))
for i in L:
print(i)
L = list(range(10))
# 把一个list变成索引-元素对
for i, x in enumerate(L):
print(i, x)
# for-in循环可以同时引用多个变量
for x, y, z in [(1, 1, 1), (2, 4, 8), (3, 9, 27)]:
print(x, y, z)
判断对象是否可迭代(Iterable)
from collections.abc import Iterable
print(isinstance('str', Iterable)) # True
print(isinstance([1, 2, 3], Iterable)) # True
print(isinstance((1, 2, 3), Iterable)) # True
print(isinstance({'1': 1, '2': 2}, Iterable)) # True
print(isinstance({1, 2, 3}, Iterable)) # True
print(isinstance(1, Iterable)) # False
迭代
dict
元素
d = {'A': 1, 'B': 2, 'C': 3}
# 迭代键值对
for k, v in d.items():
print(k, v)
# 迭代keys
for k in d.keys():
print(k)
# 迭代values
for v in d.values():
print(v)
使用迭代查找一个list中最小和最大值,并返回一个tuple
def find_min_and_max(L):
if len(L) == 0:
return None, None
minV = L[0]
maxV = L[0]
for i in range(len(L)):
if L[i] > maxV:
maxV = L[i]
if L[i] < minV:
minV = L[i]
return minV, maxV
if find_min_and_max([]) != (None, None):
print('测试失败!')
elif find_min_and_max([7]) != (7, 7):
print('测试失败!')
elif find_min_and_max([7, 1]) != (1, 7):
print('测试失败!')
elif find_min_and_max([7, 1, 3, 9, 5]) != (1, 9):
print('测试失败!')
else:
print('测试成功!')
列表生成式(List Comprehensions)
生成list
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 使用range函数
print(list(range(1, 11)))
# 使用列表生成式
print([x for x in range(1, 11)])
for循环后面还可以加上if判断,这样就可以筛选出仅偶数的平方
# [2, 4, 6, 8, 10]
print([x for x in range(1, 11) if x % 2 == 0])
使用两层循环,可以生成全排列
# ['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
print([m + n for m in 'ABC' for n in 'XYZ'])
列出当前目录下的所有文件和目录名
# ['.idea', '.venv', 'demo.py']
print([d for d in os.listdir('.')])
for循环可以使用多个变量,列表生成式也可以使用多个变量,列表生成式也可以使用两个变量来生成list
d = {'x': 'A', 'y': 'B', 'z': 'C'}
# ['x=A', 'y=B', 'z=C']
print([k + '=' + v for k, v in d.items()])
对于列表生成式,for循环前面的if需要加else,因为要计算出一个确定的值,而for循环后面的if不能加else,因为这是过滤条件
# [6, 4, 10]
# 在一个列表生成式中,for前面的if ... else是表达式,而for后面的if是过滤条件,不能带else
L = [(x if x % 2 == 0 else x * 2) for x in [1, 2, 3, 4, 5] if x > 2]
过滤出字符串并转换为小写
L1 = ['Hello', 'World', 18, 'Apple', None]
L2 = [s.lower() for s in L1 if isinstance(s, str)]
生成器(generator)
创建生成器,只需要把李彪生成式的
[]
改成()
,列表生成式会直接计算出结果,而生成器保存的是算法,每一个元素可以按照该算法推算出来
g = (x * x for x in range(10))
# <generator object <genexpr> at 0x0000015F56E7E800>
print(g)
如果要一个一个打印出来,可以通过
next()
函数获得generator的下一个返回值,直到抛出StopIteration
的错误
g = (x * x for x in range(10))
print(next(g)) # 0
print(next(g)) # 1
print(next(g)) # 2
print(next(g)) # 3
正常使用时基本不会使用
next()
方法,正确的方法是使用for
循环,因为generator也是可迭代对象,并且不需要关心StopIteration
的错误
from collections.abc import Iterable
g = (x * x for x in range(10))
print(isinstance(g, Iterable)) # True
# 使用for循环迭代生成器
for i in g:
print(i)
如果推算的算法比较复杂,用类似列表生成式的
for
循环无法实现的时候,还可以用函数来实现,比如斐波拉契数列
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
# 相当于
# t = (b, a + b) # t是一个tuple
# a = t[0]
# b = t[1]
a, b = b, a + b
n = n + 1
return 'done'
for n in fib(100):
print(n)
如果想要拿到返回值,必须捕获StopIteration
错误。
g = fib(10)
while True:
try:
x = next(g)
print('g:', x)
except StopIteration as e:
print('Generator return value:', e.value)
break
如果一个函数定义中包含
yield
关键字,那么这个函数就不再是一个普通函数,而是一个generator函数,调用一个generator函数将返回一个generator
# <generator object fib at 0x000002253550EEA0>
print(fib(100))
生成器在每次调用
next()
的时候执行,遇到yield
语句返回,再次执行时从上次返回的yield
语句处继续执行,比如
def odd():
print('step 1')
yield 1
print('step 2')
yield (3)
print('step 3')
yield (5)
# 每次调用生成器函数会返回一个全新的生成器
g = odd()
print(next(g)) # 1
print(next(g)) # 2
print(next(g)) # 3
杨辉三角定义如下:
1
/ \
1 1
/ \ / \
1 2 1
/ \ / \ / \
1 3 3 1
/ \ / \ / \ / \
1 4 6 4 1
/ \ / \ / \ / \ / \
1 5 10 10 5 1
把每一行看做一个list,试写一个generator,不断输出下一行的list:
评论区