一、迭代器
有__iter__方法的对象,都是可迭代对象。
lis = [1,2]
print(lis.__iter__)
<method-wrapper '__iter__' of list object at 0x000001B3820A1A40>
Python内置str、list、tuple、dict、set、file都是可迭代对象。
文件既是可迭代对象又是迭代器对象
可迭代的对象执行__iter__方法得到的返回值就是迭代器
迭代器对象有.__next__方法 # 更加节省内存,for循环本质
s = 'hello'
iter_s = s.__iter__() # 迭代器对象
while True:
try:
print(iter_s.__next__())
except StopIteration:
break
h
e
l
l
o
print(iter_s)
print(iter_s.__iter__().__iter__()) # 迭代器对象内置有\_\_iter\_\_方法,执行该方法会拿到迭代器本身
<str_ascii_iterator object at 0x000001B3820E8A30>
<str_ascii_iterator object at 0x000001B3820E8A30>
二、三元表达式 # 不推荐使用
条件成立返回值 if 条件 else 条件不成立时的返回值
x = '吃饭'
y = '饿了'
z = '玩游戏'
print(x) if y == '饿了' else print(z)
吃饭
三、列表推导式/字典生成式 # 不推荐使用
推导列表
[expression for item1 in iterable1 if condition1
for item2 in iterable2 if condition2
...
for itemN in iterableN if conditionN
]
lis=['*' for i in range(20) if True]+['.' for i in range(10)]
lis1=[i for i in range(20)]
print(lis)
print(lis1)
['*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.']
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
生成字典
dic = {i: 0 for i in range(20)}
dic1 = dict.fromkeys([1,2,3,4],'*')
print(dic)
print(dic1)
{0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0, 13: 0, 14: 0, 15: 0, 16: 0, 17: 0, 18: 0, 19: 0}
{1: '*', 2: '*', 3: '*', 4: '*'}
拉链函数zip() # 取一次就没了
res = zip('abcd',[1,2,3,4],[5,6,7,9])
for i in res:
print(i)
print(res)
res = zip('abcd',[1,2,3,4])
for k,v in res:
print(k,v)
res = zip('abcd',[1,2,3,4])
info_dict = {k: v for k, v in res}
print(info_dict)
('a', 1, 5)
('b', 2, 6)
('c', 3, 7)
('d', 4, 9)
<zip object at 0x000001B383EB7100>
a 1
b 2
c 3
d 4
{'a': 1, 'b': 2, 'c': 3, 'd': 4}
四、生成器#自定义的迭代器
yield# 接收函数值但是不会结束函数,而是继续运行下一行代码
每次调用 next() 时,函数从上次 yield 的位置恢复执行
所有局部变量状态都会被保留
def func():
print(1)
yield
print(2)
yield
g = func()
for i in g :
print(i)
1
None
2
None
# 生成无限序列(不占用无限内存)
def infinite_counter():
n = 0
while True:
yield n
n += 1
counter = infinite_counter()
print(next(counter)) # 0
print(next(counter)) # 1
0
1
生成器表达式 #了解
t = (i for i in range(10)) #就是这个
print(t)
print(f"next(t): {next(t)}")
for i in t:
print(i)
<generator object <genexpr> at 0x00000276E07BF400>
next(t): 0
1
2
3
4
5
6
7
8
9
五、递归
函数的递归调用:它是一种特殊的嵌套调用,但是它在调用一个函数的过程中,又直接或间接地调用了它自身。
def count(x):
x += 1
print(x)
if x == 21:
return
count(x)
count(0)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def age(n):
if n == 1:
return 26
return age(n-1) + 2
print(f"age(5): {age(5)}")
# age(5)
# =age(4)+2
# =age(3)+2+2
# ....
age(5): 34
lis = [i for i in range(1000)]
i = 0
def fin(x,i):
i += 1
if lis[i] == x:
print(f'找到了!在{i}')
return
fin(x,i)
fin(506,0)
找到了!在506
import time
lis = [i for i in range(10000000)]
def deco(func):
def wrapper(*args,**kwargs):
start = time.time()
res = func(*args,**kwargs)
end = time.time()
print(end-start)
return res
return wrapper
@deco
def fin(x):
for i in lis:
if i == x:
print(f'找到了,在{i}')
break
else:
print('找不到')
fin(512352)
找到了,在512352
0.011513233184814453
<function __main__.deco.<locals>.wrapper(*args, **kwargs)>
二分法
lis = [i for i in range(100)] # 有序列表 [0, 1, 2, ..., 99]
x = 2 # 目标值
# 初始化边界指针
low = 0
high = len(lis) - 1 # 索引从0开始,所以high=99
found = False # 标记是否找到
while low <= high: # 当 low <= high 时,范围有效
mid = (low + high) // 2 # 计算中间索引
print(f"当前索引 mid={mid}, 值={lis[mid]}") # 调试打印,可选
if lis[mid] == x:
print(f'找到了! 索引位置: {mid}')
found = True
break
elif lis[mid] < x:
low = mid + 1 # 目标在右侧,缩小范围到右半部分
else: # lis[mid] > x
high = mid - 1 # 目标在左侧,缩小范围到左半部分
if not found:
print('没找到!') # 处理目标不存在的情况
当前索引 mid=49, 值=49
当前索引 mid=24, 值=24
当前索引 mid=11, 值=11
当前索引 mid=5, 值=5
当前索引 mid=2, 值=2
找到了! 索引位置: 2
lis = [i for i in range(100)]
x = 1
low = 0
high = len(lis)-1
mid = (low+high)//2
while low <= high:
print(mid)
if lis[mid] == x:
print('找到了!')
break
elif lis[mid] > x:
high = mid - 1
mid = (low+high)//2
elif lis[mid] < x:
low = mid + 1
mid = (low+high)//2
else:
print('没找到')
49
24
11
5
2
0
1
找到了!
def binary_search_recursive(arr, x, low, high):
# 基线条件:搜索范围无效,未找到
if low > high:
return -1
# 计算中间索引
mid = (low + high) // 2
# 调试信息:显示当前搜索范围
print(f"搜索范围: [{low}-{high}], 中间索引: {mid}, 值: {arr[mid]}")
# 检查中间值
if arr[mid] == x:
return mid # 找到目标,返回索引
elif arr[mid] > x:
# 目标在左半部分,递归搜索左侧
return binary_search_recursive(arr, x, low, mid - 1)
else:
# 目标在右半部分,递归搜索右侧
return binary_search_recursive(arr, x, mid + 1, high)
# 测试数据
lis = [i for i in range(100)]
x = 75
# 初始调用
result = binary_search_recursive(lis, x, 0, len(lis) - 1)
# 输出结果
if result != -1:
print(f"找到了! 索引位置: {result}")
else:
print("没找到")
搜索范围: [0-99], 中间索引: 49, 值: 49
搜索范围: [50-99], 中间索引: 74, 值: 74
搜索范围: [75-99], 中间索引: 87, 值: 87
搜索范围: [75-86], 中间索引: 80, 值: 80
搜索范围: [75-79], 中间索引: 77, 值: 77
搜索范围: [75-76], 中间索引: 75, 值: 75
找到了! 索引位置: 75
def binary_search(arr, x):
# 内部定义的递归辅助函数
def _search(low, high):
# 基线条件:搜索范围无效,未找到
if low > high:
return -1
# 计算中间索引
mid = (low + high) // 2
# 调试信息(可选)
# print(f"搜索范围: [{low}-{high}], 中间索引: {mid}, 值: {arr[mid]}")
# 检查中间值
if arr[mid] == x:
return mid
elif arr[mid] > x:
return _search(low, mid - 1) # 搜索左侧
else:
return _search(mid + 1, high) # 搜索右侧
# 初始调用辅助函数,使用整个数组范围
return _search(0, len(arr) - 1)
# 测试代码
lis = [i for i in range(100)]
x = 75
result = binary_search(lis, x)
if result != -1:
print(f"找到了! 索引位置: {result}")
else:
print("没找到")
找到了! 索引位置: 75
0 1 1 2 3 5 8 13 . . . . . . . . .
def f(n):
if n == 1:
return 0
if n == 2:
return 1
return f(n-1) + f(n-2)
def lie(x):
lis = list()
for i in range(1,x+1):
lis.append(f(i))
return lis
print(lie(11))
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
def f(n):
lis = [0,1]
if n == 0:
return []
if n == 1:
return [0]
for i in range(2, n):
lis.append(lis[-1] + lis[-2])
return lis
print(f(20))
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181]
浙公网安备 33010602011771号