当前位置:   article > 正文

竞赛中常用的Python 标准库_蓝桥杯python能用哪些库

蓝桥杯python能用哪些库

对竞赛中常用得标准库进行解析和给出代码模板

题型


1.思维题/杂题:数学公式,分析题意,找规律

2.BFS/DFS:广搜(递归实现),深搜(deque实现)

3.简单数论:模,素数(只需要判断到 int(sqrt(n))+1),埃式筛,gcd,lcm,快速幂(位运算移位操作),大数分解(分解为质数的乘积)

4.简单图论:最短路(一对多(Dijstra,临接表,矩阵实现),多对多(Floyd,矩阵实现)),最小生成树(并查集实现Kruskal算法,Prim算法),Floyd,DIjstra,Bellman-Ford,SPFA

5.简单字符串处理:最好转为列表操作

6.DP:线性DP,最长公共子序列,0/1背包问题,最长连续字符串,最大递增子串,数位DP,树形DP,区间DP,状态压缩DP(借用位运算)

7.基本算法:二分,贪心,组合,排列,前缀和,差分,倍增

8.基本数据结构:队列,集合,字典,字符串,列表,栈,树

9.高级数据结构:并查集,带权并查集,树状数组,线段树

10.字符串:KMP算法,哈希算法,回文字符串

11.常用模块:math,datetime,sys中的设置最大递归深(sys.setrecursionlimit(3000000)),collections.deque(队列),itertools.combinations(list,n)(组合),itertools.permutations(list,n)(排列)  heapq(小顶堆)bisect(二分)


1.functools

1.1  cmp_to_key

将旧风格的比较函数转换为key函数。

-1 不变 1 交换位置

  1. import functools
  2. x=[1,3,2,4,5]
  3. def cmp_rise(a,b):
  4. '''
  5. 升序排序:
  6. 当前面的参数a小于后面的参数b返回-1,-1代表保持不变,
  7. 当前面的的参数a大于等于后面的参数b返回1,1代表交换顺序。
  8. 因此保证了前面的数子小于后面的数字,是升序排序。
  9. '''
  10. if a <b:
  11. return -1
  12. else:
  13. return 1
  14. def cmp_decline(a,b):
  15. '''
  16. 降序排序:
  17. 当前面的参数a小于后面的参数b返回1,1代表交换顺序,
  18. 当前面的的参数a大于等于后面的参数b返回-1,-1代表保持不变。
  19. 因此保证了前面的数子大于后面的数字,是降序排序。
  20. '''
  21. if a <b:
  22. return 1
  23. else:
  24. return -1
  25. x_sorted_by_rise=sorted(x,key=functools.cmp_to_key(cmp_rise))
  26. x_sorted_by_decline=sorted(x,key=functools.cmp_to_key(cmp_decline))
  27. print(x) # 输出结果:[1, 3, 2, 4, 5]
  28. print(x_sorted_by_rise) # 输出结果:[1, 2, 3, 4, 5]
  29. print(x_sorted_by_decline) # 输出结果:[5, 4, 3, 2, 1]

1.2  lru_cache(记忆化存储,加快递归速度)

允许我们将一个函数的返回值快速地缓存或取消缓存。
装饰器用于缓存函数的调用结果,对于需要多次调用的函数,而且每次调用参数都相同,则可以用该装饰器缓存调用结果,从而加快程序运行。
该装饰器会将不同的调用结果缓存在内存中,因此需要注意内存占用问题。

  1. from functools import lru_cache
  2. @lru_cache(maxsize=30) # maxsize参数告诉lru_cache缓存最近多少个返回值
  3. def fib(n):
  4. if n < 2:
  5. return n
  6. return fib(n-1) + fib(n-2)
  7. print([fib(n) for n in range(10)])
  8. fib.cache_clear() # 清空缓存

2.collections

2.1 deque

双端队列,用于实现单调队列和BFS搜索

  1. from collections import deque
  2. q = deque(['a', 'b', 'c'], maxlen=10)
  3. # 从右边添加一个元素
  4. q.append('d')
  5. print(q) # deque(['a', 'b', 'c', 'd'], maxlen=10)
  6. # 从左边删除一个元素
  7. print(q.popleft()) # a
  8. print(q) # deque(['b', 'c', 'd'], maxlen=10)
  9. # 扩展队列
  10. q.extend(['i', 'j'])
  11. print(q) # deque(['b', 'c', 'd', 'i', 'j'], maxlen=10)
  12. # 查找下标
  13. print(q.index('c')) # 1
  14. # 移除第一个'd'
  15. q.remove('d')
  16. print(q) # deque(['b', 'c', 'i', 'j'], maxlen=10)
  17. # 逆序
  18. q.reverse()
  19. print(q) # deque(['j', 'i', 'c', 'b'], maxlen=10)
  20. # 最大长度
  21. print(q.maxlen) # 10

2.1.1 单调对列实现

蓝桥杯 MAX最值差

  1. import os
  2. import sys
  3. # 请在此输入您的代码
  4. from collections import deque
  5. def findMaxdiff(n,k,a):
  6. q1,q2=deque(),deque() # 建两个单调队列
  7. res=-sys.maxsize
  8. for i in range (n): # 遍历每一个元素
  9. while q1 and a[q1[-1]]>=a[i]: #q1有元素且最后一个元素都大于a[i]
  10. q1.pop()
  11. q1.append(i)
  12. while q1 and i-q1[0]>=k:
  13. q1.popleft()
  14. Fi=a[q1[0]]
  15. while q2 and a[q2[-1]]<=a[i]: #q1有元素且最后一个元素都大于a[i]
  16. q2.pop()
  17. q2.append(i)
  18. while q2 and i-q2[0]>=k:
  19. q2.popleft()
  20. Gi=a[q2[0]]
  21. #计算最大差值
  22. res=max(res,Gi-Fi)
  23. return res
  24. n,k=map(int,input().split())
  25. A=list(map(int,input().split()))
  26. print(findMaxdiff(n,k,A))

2.1.2 BFS广搜

蓝桥杯真题 跳蚂蚱

  1. import collections
  2. import sys
  3. meet=False #判断是否相遇
  4. def extend(q,m1,m2):
  5. global meet
  6. s=q.popleft()
  7. ss=list(s)
  8. index=ss.index('0') #找0的索引
  9. for j in [1,-1,2,-2]:
  10. ss[(index+j+9)%9],ss[index]= ss[index],ss[(index+j+9)%9]
  11. a=''.join(ss)
  12. if a in m2: # 找到相同的了,即相遇了
  13. print(m1[s]+1+m2[a])
  14. meet=True
  15. return
  16. if a not in m1:
  17. q.append(a)
  18. m1[a]=m1[s]+1 # 向字典中添加
  19. ss[(index+j+9)%9],ss[index]= ss[index],ss[(index+j+9)%9]
  20. # meet=False
  21. q1=collections.deque()
  22. q2=collections.deque()
  23. q1.append("012345678")
  24. q2.append("087654321")
  25. # 字典去重,同时记录步数
  26. mp1={'012345678':0} ; mp2={'087654321':0}
  27. while q1 and q2 : # 两个都不为空
  28. if len(q1)<=len(q2): extend(q1,mp1,mp2)
  29. else: extend(q2,mp2,mp1)
  30. if meet==True: break

3.sys

3.1 sys.maxsize

表示操作系统承载的最大int值

3.2 sys.exit()

中断程序运行

3.3 sys.stdin.readline()

快读,注意会读入回车符,感觉用处不大, 没提升多大效率

  1. import sys
  2. a = sys.stdin.readline()
  3. b = input()
  4. print(len(a), len(b))
  5. a = sys.stdin.readline().strip('\n')
  6. b = input()
  7. print(len(a), len(b))
  8. 输出结果
  9. 123123 123123 adsfasdfd fefeggegeag fasdfa
  10. 123123 123123 adsfasdfd fefeggegeag fasdfa
  11. 43 42
  12. 123123 123123 adsfasdfd fefeggegeag fasdfa
  13. 123123 123123 adsfasdfd fefeggegeag fasdfa
  14. 42 42

3.4  sys.setrecursionlimit()

设置最大递归深度,默认的很小,有时候dfs会报错出现段错误。

sys.setrecursionlimit(10**6)

4.heapq

4.1 heapq.heapify(x)

将list x 转换成堆,原地,线性时间内。

  1. import heapq
  2. H = [21,1,45,78,3,5]
  3. # Use heapify to rearrange the elements
  4. heapq.heapify(H)
  5. print(H)
  6. [1, 3, 5, 78, 21, 45]

4.2 heapq.heappush(heap, item)

将 item 的值加入 heap 中,保持堆的不变性。

  1. # Add element
  2. heapq.heappush(H,8)
  3. print(H)
  4. [1, 3, 5, 78, 21, 45]
  5. [1, 3, 5, 78, 21, 45, 8]

4.3 heapq.heappop(heap)

弹出并返回 heap 的最小的元素,保持堆的不变性。如果堆为空,抛出 IndexError 。使用 heap[0] ,可以只访问最小的元素而不弹出它。

  1. # Remove element from the heap
  2. heapq.heappop(H)
  3. print(H)
  4. [1, 3, 5, 78, 21, 45, 8]
  5. [3, 21, 5, 78, 45]

4.4 堆优化的Dijstra 

1.蓝桥杯国赛真题 出差

  1. import os
  2. import sys
  3. import itertools
  4. import heapq
  5. # Bellman-Ford O(mn)
  6. '''
  7. n,m=map(int,input().split())
  8. stay=[0]+list(map(int,input().split()))
  9. stay[n]=0 # 终点不需要隔离
  10. e=[]
  11. for i in range(m):
  12. a,b,c=map(int,input().split())
  13. e.append([a,b,c])
  14. e.append([b,a,c])
  15. dp=[sys.maxsize for i in range(n+1)]
  16. dp[1]=0 #到起点的距离为0
  17. for i in range(1,n+1): # n个点
  18. for j in e: # m条边
  19. v1,v2,cost=j
  20. #if v2==n: # n号城市不需要隔离时间
  21. dp[v2]=min(dp[v2],dp[v1]+cost+stay[v2])
  22. print(dp[n])
  23. '''
  24. # Dijstra 临接表写法 O(n*n)
  25. '''
  26. n,m=map(int,input().split())
  27. stay=[0]+list(map(int,input().split()))
  28. stay[n]=0 # 终点不需要隔离
  29. edge=[[]for i in range(n+1)]
  30. for i in range(m):
  31. a,b,c=map(int,input().split())
  32. edge[a].append([b,c+stay[b]])
  33. edge[b].append([a,c+stay[a]])
  34. hp=[]
  35. vis=[0 for i in range(n+1)]
  36. dp=[sys.maxsize for i in range(n+1)]
  37. dp[1]=0 # 自身到自身距离为0
  38. heapq.heappush(hp,(0,1))
  39. while hp:
  40. u=heapq.heappop(hp)[1]
  41. if vis[u]:
  42. continue
  43. vis[u]=1
  44. for i in range(len(edge[u])): # 遍历u的边
  45. v,w=edge[u][i][0],edge[u][i][1]
  46. if vis[v]:
  47. continue
  48. if dp[v]>dp[u]+w:
  49. dp[v]=dp[u]+w
  50. heapq.heappush(hp,(dp[v],v))
  51. print(dp[n])
  52. '''
  53. # Dijstra临接矩阵写法 O(n*n)
  54. '''
  55. n,m=map(int,input().split())
  56. stay=[0]+list(map(int,input().split()))
  57. stay[n]=0 # 终点不需要隔离
  58. edge=[[sys.maxsize for i in range(n+1)]for i in range(n+1)]
  59. for i in range(m):
  60. a,b,c=map(int,input().split())
  61. edge[a][b]=c+stay[b]
  62. edge[b][a]=c+stay[a]
  63. vis=[0 for i in range(n+1)]
  64. dp=[sys.maxsize for i in range(n+1)]
  65. dp[1]=0 # 自身到自身距离为0
  66. for i in range(n-1): #只需要处理n-1个点
  67. t=-1
  68. for j in range(1,n+1): # 找到没处理过得并且距离最小的
  69. if vis[j]==0 and(t==-1 or dp[j]<dp[t] ):
  70. t=j
  71. for j in range(1,n+1):
  72. dp[j]=min(dp[j],dp[t]+edge[t][j])
  73. vis[t]=1
  74. print(dp[n])
  75. '''
  76. # SPFA
  77. n,m=map(int,input().split())
  78. stay=[0]+list(map(int,input().split()))
  79. stay[n]=0 # 终点不需要隔离
  80. edge=[[]for i in range(n+1)] #临接表存边
  81. for i in range(m):
  82. a,b,c=map(int,input().split())
  83. edge[a].append([b,c+stay[b]])
  84. edge[b].append([a,c+stay[a]])
  85. dp=[sys.maxsize for i in range(n+1)]
  86. dp[1]=0 # 自身到自身距离为0
  87. def spfa():
  88. hp=[]
  89. heapq.heappush(hp,1) #用堆实现相当于优先队列,加快一点效率罢了
  90. in_hp=[0 for i in range(n+1)] # 标记数组换为了判断是否在队列中
  91. in_hp[1]=1 # 1在队列
  92. while hp:
  93. u=heapq.heappop(hp)
  94. in_hp[u]=0 # 标记为不在队列
  95. if dp[u]==sys.maxsize: # 没有处理过的点,直接跳过,只处理邻居点
  96. continue
  97. for i in range(len(edge[u])): # 遍历u的边
  98. v,w=edge[u][i][0],edge[u][i][1]
  99. if dp[v]>dp[u]+w:
  100. dp[v]=dp[u]+w
  101. if in_hp[v]==0: # 他的邻居不再队列,就把他入队,方便下下次更新邻居的邻居结点
  102. heapq.heappush(hp,v)
  103. in_hp[v]=1
  104. spfa()
  105. print(dp[n])

4.5 通过堆实现的Kruskal算法

1.国赛真题 通电

  1. import os
  2. import sys
  3. import math
  4. import heapq # heapq 比 优先队列要快很多
  5. input = sys.stdin.readline
  6. n = int(input().strip())
  7. root = [i for i in range(n+1)]
  8. arr = [list(map(int, input().strip().split())) for i in range(n)] # n个点坐标 高度
  9. # 计算距离
  10. def dist(x1,y1,h1, x2,y2,h2):
  11. return math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)) + (h1-h2)*(h1-h2)
  12. q = []
  13. # 建立 n个点的的连通图
  14. for i in range(n):
  15. for j in range(i+1,n):
  16. heapq.heappush(q, [dist(arr[i][0],arr[i][1],arr[i][2], arr[j][0],arr[j][1],arr[j][2]), i, j]) # 从 i到j牵线,并按距离排序
  17. # 判断是否会形成环
  18. def find(u):
  19. if u != root[u]:
  20. root[u] = find(root[u])
  21. return root[u]
  22. # Kruskal 算法实现步骤
  23. def Kruskal():
  24. ans = 0.00
  25. cnt = 0
  26. while q and cnt < n-1: # 图只需找n-1条边
  27. c,a,b = heapq.heappop(q)
  28. a_root = find(a)
  29. b_root = find(b)
  30. if a_root != b_root:
  31. root[a_root] = b_root
  32. ans += c
  33. cnt += 1
  34. print('%.2lf' % ans)
  35. Kruskal()
  36. """
  37. import os
  38. import sys
  39. # 请在此输入您的代码
  40. import math
  41. n=int(input())
  42. def money(a,b):
  43. ke=math.sqrt(pow(a[0]-b[0],2)+pow(a[1]-b[1],2))+pow(a[2]-b[2],2)
  44. return ke
  45. def prim():
  46. global res
  47. dist[0]=0
  48. book[0]=1
  49. for i in range(1,n):
  50. dist[i]=min(dist[i],G[0][i])
  51. for i in range(1,n):
  52. cnt=float("inf")
  53. t=-1
  54. for j in range(1,n):
  55. if book[j]==0 and dist[j]<cnt:
  56. cnt=dist[j]
  57. t=j
  58. if t==-1 :
  59. res=float("inf")
  60. return
  61. book[t]=1
  62. res+=dist[t]
  63. for j in range(1,n):
  64. dist[j]=min(dist[j],G[t][j])
  65. ls=[]
  66. book=[0]*n
  67. dist=[float("inf")]*n
  68. res=0
  69. for i in range(n):
  70. ls.append(list(map(int,input().split())))
  71. G=[[float("inf")]*n for _ in range(n)]
  72. for i in range(n):
  73. G[i][i]=float("inf")
  74. for i in range(n):
  75. for j in range(i+1,n):
  76. G[i][j]=money(ls[i],ls[j])
  77. G[j][i]=money(ls[i],ls[j])
  78. prim()
  79. print("{:.2f}".format(res))
  80. """

5.itertools

主要使用combinations和combinations。

5.1 combinations

itertools.combinations(iterable, r):生成可迭代对象的所有长度为r的组合。

5.2 permutations

itertools.permutations(iterable, r=None):生成可迭代对象的所有长度为r的排列,默认r为可迭代对象的长度。

5.3 例题

1.算式问题 

  1. import os
  2. import sys
  3. import itertools
  4. # 请在此输入您的代码
  5. L=[str(i) for i in range(1,10)]
  6. ans=0
  7. for i in itertools.permutations(L):
  8. s=''.join(i)
  9. if int(s[:3])+int(s[3:6])==int(s[6:]):
  10. ans+=1
  11. print(ans)

6.bisect

内置的二分查找函数,用于有序序列的插入和查找

 6.1 bisect_left()

bisect.bisect_left(a, x, lo=0, hi=len(a))

若 x ∈ a,返回最左侧 x 的索引;否则返回与 x 右邻居索引,使得 x 若插入后能位于其 左侧。 

6.2 bisect_right() 、bisect()

  1. bisect.bisect(a, x, lo = 0, hi =len(a))
  2. bisect.bisect_right(a, x, [lo=0, hi=len(a)])

若 x ∈ a,返回最左侧 x 的索引;否则返回与 x 右邻居索引,使得 x 若插入后能位于其 左侧。 

6.3 insort_left()

bisect.insort_left(a, x, lo=0, hi=len(a))

bisect.bisect_left() 在序列 a 中 查找 元素 x 的插入点 (左侧)
bisect.insort_left() 就是在找到插入点的基础上,将元素 x 插入序列 a,从而改变序列 a 同时保持元素顺序。

6.4 insort_right()、insort()

  1. bisect.insort(a, x, lo=0, hi=len(a))
  2. bisect.insort_right(a, x, lo=0, hi=len(a))

6.5 示例

  1. import bisect
  2. nums = [0,1,2,3,4,4,6]
  3. idx = bisect.bisect_left(nums,-1) # 0
  4. idx = bisect.bisect_left(nums,8) # 7
  5. idx = bisect.bisect_left(nums,3) # 3
  6. idx = bisect.bisect_left(nums,3.5) # 4
  7. idx = bisect.bisect_left(nums,4) # 4
  8. idx = bisect.bisect_left(nums,3,1,4) # 3
  9. a = [1,4,6,8,12,15,20]
  10. position = bisect.bisect(a,13)
  11. print(position) # 5
  12. # 用可变序列内置的 insert 方法插入
  13. a.insert(position, 13)
  14. print(a) # 5 [1, 4, 6, 8, 12, 13, 15, 20]

 查找的数不在列表中

  1. import bisect
  2. list1 = [1,3,5,7,9,11,11,11,11,11,13]
  3. a = bisect.bisect(list1,6)
  4. b = bisect.bisect_left(list1,6)
  5. c = bisect.bisect_right(list1,6)
  6. print(a,b,c)
  7. # 输出为 3,3,3

 查找的数在列表中只有一个

  1. import bisect
  2. list1 = [1,3,5,7,9,11,11,11,11,11,13]
  3. a = bisect.bisect(list1,9)
  4. b = bisect.bisect_left(list1,9)
  5. c = bisect.bisect_right(list1,9)
  6. print(a,b,c)
  7. # 输出 5,4,5

查找的数在列表中有多个

  1. import bisect
  2. list1 = [1,3,5,7,9,11,11,11,11,11,13]
  3. a = bisect.bisect(list1,11)
  4. b = bisect.bisect_left(list1,11)
  5. c = bisect.bisect_right(list1,11)
  6. print(a,b,c)
  7. # 输出是 10,5,10

6.6 例题1 最长上升子序列

1.蓝桥骑士

  1. import os
  2. import sys
  3. '''
  4. # 最长上升子序列
  5. n = int(input())
  6. a = list(map(int,input().split()))
  7. f = [1]*n
  8. for i in range(1,n):
  9. for j in range(i):
  10. if a[i] > a[j]:
  11. f[i] = max(f[i],f[j]+1)
  12. print(max(f))
  13. '''
  14. # 超时
  15. '''
  16. import bisect
  17. n = int(input())
  18. a = list(map(int,input().split()))
  19. b = [a[0]]
  20. for i in range(1,n):
  21. t = bisect.bisect_left(b,a[i])
  22. # 若b中不存在a[i],t是适合插入的位置
  23. # 若b中存在a[i],t是a[i]第一个出现的位置
  24. if t == len(b): # 插入的位置是否是末尾
  25. b.append(a[i])
  26. else:
  27. b[t] = a[i]
  28. print(len(b))
  29. '''
  30. import bisect
  31. #蓝桥骑士 dp lis(Longest Increasing Subsequence)
  32. n = int(input())
  33. alist = list(map(int,input().split()))
  34. dp = []
  35. for i in alist:
  36. if not dp or i > dp[-1]:
  37. dp.append(i)
  38. else:
  39. index = bisect.bisect_left(dp,i)
  40. dp[index]=i
  41. print(len(dp))

 2.蓝桥勇士

  1. import sys #设置递归深度
  2. import collections #队列
  3. import itertools # 排列组合
  4. import heapq #小顶堆
  5. import math
  6. sys.setrecursionlimit(300000)
  7. n=int(input())
  8. save=[0]+list(map(int,input().split()))
  9. dp=[1]*(n+1) # 注意初始化从1开始
  10. for i in range(2,n+1):
  11. for j in range(1,i):
  12. if save[i]>save[j]:
  13. dp[i]=max(dp[i],dp[j]+1)
  14. print(max(dp)) #最长公共子序列,dp[n]不一定是最大的
  15. # 1 4 5 2 1
  16. # 1 2 3 2 1

6.7 例题2 最长上升子序列变形

  1. import bisect # 内置二分查找
  2. zifu = input()
  3. A = [chr(65 + i) for i in range(26)]
  4. s = ""
  5. name = []
  6. i = 0
  7. zifu = zifu + "A" # 以后一个大写字符进行提取分隔
  8. while i < len(zifu) - 1: # 提取数据格式为 name=[Wo,Ai,Lan,Qiao,Bei]
  9. s += zifu[i]
  10. if zifu[i + 1] in A:
  11. name.append(s)
  12. s = ""
  13. i += 1
  14. d = [name[0]]
  15. p=[1] #存储下标
  16. for i in name[1:]: # 遍历每一个字符
  17. if i > d[-1]: # 大于,可以直接在后面接着
  18. d.append(i) # 后面添加
  19. p.append(len(d)) # 记录索引
  20. else: # 查找第一个
  21. k = bisect.bisect(d, i) # 使用bisect查找d中第一个大于等于i的元素,让其称为递增序列,有多个就是最右边的那个
  22. if k > 0 and d[k - 1] == i: # 如果右索引的前一个数等于这个i的话,就将它替换掉,相等的不算递增????
  23. k -= 1
  24. d[k] = i
  25. p.append(k+1) # 记录替换的索引
  26. p0=p[::-1] #逆序遍历输出
  27. s=len(d) # 最长有多少个递增子序列
  28. ans=""
  29. for i in range(len(p0)): #逆序遍历
  30. if s==0:
  31. break
  32. if p0[i]==s:
  33. ans=name[len(p)-i-1]+ans #加上name
  34. s=s-1
  35. print(ans)

Python知识教程

1.Python简介

  • Python 是一种解释型语言: 这意味着开发过程中没有了编译这个环节。类似于PHP和Perl语言。

  • Python 是交互式语言: 这意味着,您可以在一个 Python 提示符 >>> 后直接执行代码。

  • Python 是面向对象语言: 这意味着Python支持面向对象的风格或代码封装在对象的编程技术。

  • Python 是初学者的语言:Python 对初级程序员而言,是一种伟大的语言,它支持广泛的应用程序开发,从简单的文字处理到 WWW 浏览器再到游戏。

2.Python中标准数据类型

常见数据类型

  • Number(数字)
  • String(字符串)
  • bool(布尔类型)
  • List(列表)
  • Tuple(元组)
  • Set(集合)
  • Dictionary(字典)

Python3 的六个标准数据类型中:

  • 不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);
  • 可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。

3.Python3迭代器与生成器

迭代器

迭代器是一个可以记住遍历的位置的对象。

迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

迭代器有两个基本的方法:iter() 和 next()

迭代器的创建

把一个类作为一个迭代器使用需要在类中实现两个方法 __iter__() 与 __next__() 。

  1. class MyNumbers:
  2. def __iter__(self):
  3. self.a = 1
  4. return self
  5. def __next__(self):
  6. x = self.a
  7. self.a += 1
  8. return x
  9. myclass = MyNumbers()
  10. myiter = iter(myclass)
  11. print(next(myiter))
  12. print(next(myiter))
  13. print(next(myiter))
  14. print(next(myiter))
  15. print(next(myiter))

输出结果

1
2
3
4
5

生成器

在 Python 中,使用了 yield 的函数被称为生成器(generator)。

yield 是一个关键字,用于定义生成器函数,生成器函数是一种特殊的函数,可以在迭代过程中逐步产生值,而不是一次性返回所有结果。

跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

当在生成器函数中使用 yield 语句时,函数的执行将会暂停,并将 yield 后面的表达式作为当前迭代的值返回。

然后,每次调用生成器的 next() 方法或使用 for 循环进行迭代时,函数会从上次暂停的地方继续执行,直到再次遇到 yield 语句。这样,生成器函数可以逐步产生值,而不需要一次性计算并返回所有结果。

代码实例

  1. def countdown(n):
  2. while n > 0:
  3. yield n
  4. n -= 1
  5. # 创建生成器对象
  6. generator = countdown(5)
  7. # 通过迭代生成器获取值
  8. print(next(generator)) # 输出: 5
  9. print(next(generator)) # 输出: 4
  10. print(next(generator)) # 输出: 3
  11. # 使用 for 循环迭代生成器
  12. for value in generator:
  13. print(value) # 输出: 2 1

 4.Python面向对象

面向对象简介

  • 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
  • 方法:类中定义的函数。
  • 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
  • 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
  • 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
  • 局部变量:定义在方法中的变量,只作用于当前实例的类。
  • 实例变量:在类的声明中,属性是用变量来表示的,这种变量就称为实例变量,实例变量就是一个用 self 修饰的变量。
  • 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
  • 实例化:创建一个类的实例,类的具体对象。
  • 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/451886
推荐阅读
相关标签
  

闽ICP备14008679号