Python学习笔记 (4) :迭代器、生成器、装饰器、递归、正则表达式等

迭代器

迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退。另外,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件

特点:

  1. 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
  2. 不能随机访问集合中的某个值 ,只能从头到尾依次访问
  3. 访问到一半时不能往回退
  4. 便于循环比较大的数据集合,节省内存
 a=iter([1,2,3,4,5])
print(a.__next__())
print(a.__next__())
print(a.__next__())
print(a.__next__())
print(a.__next__())

迭代器

运行代码:

D:\Python34\python.exe C:/Users/AMTF/PycharmProjects/S12/day1/ifelse.py
1
2
3
4
5

生成器generator
定义:一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator),如果函数中包含yield语法,那这个函数就会变成生成器

 def cash_out(amount):
while amount >0:
amount -= 1
yield 1
print("擦,又来取钱了。。。败家子!")
ATM = cash_out(5)
print("取到钱 %s 万" % ATM.__next__())
print("花掉花掉!")
print("取到钱 %s 万" % ATM.__next__())
print("取到钱 %s 万" % ATM.__next__())
print("花掉花掉!")
print("取到钱 %s 万" % ATM.__next__())
print("取到钱 %s 万" % ATM.__next__())
print("取到钱 %s 万" % ATM.__next__()) #到这时钱就取没了,再取就报错了
print("取到钱 %s 万" % ATM.__next__())

生成器

运行代码:

取到钱 1 万
花掉花掉!
擦,又来取钱了。。。败家子!
取到钱 1 万
擦,又来取钱了。。。败家子!
取到钱 1 万
花掉花掉!
擦,又来取钱了。。。败家子!
取到钱 1 万
擦,又来取钱了。。。败家子!
取到钱 1 万
擦,又来取钱了。。。败家子!
Traceback (most recent call last):
  File "C:/Users/AMTF/PycharmProjects/S12/day1/ifelse.py", line 18, in <module>
    print("取到钱 %s 万" % ATM.__next__()) #到这时钱就取没了,再取就报错了
StopIteration

作用:

这个yield的主要效果呢,就是可以使函数中断,并保存中断状态,中断后,代码可以继续往下执行,过一段时间还可以再重新调用这个函数,从上次yield的下一句开始执行。

 import time
def consumer(name):
print("%s 准备吃包子了!"%name)
while True:
baozi=yield
print(("包子【%s】来了,被[%s]吃了")%(baozi,name))
def producer(name):
c=consumer("a")
c2=consumer("b")
c.__next__()
c2.__next__()
print("老子开始做包子了!")
for i in range(1,4):
time.sleep(1)
print("做了两个包子!")
c.send(i)
c2.send(i)
producer("alex")

使用yield实现单线程的一部并发效果

运行代码:

a 准备吃包子了!
b 准备吃包子了!
老子开始做包子了!
做了两个包子!
包子【1】来了,被[a]吃了
包子【1】来了,被[b]吃了
做了两个包子!
包子【2】来了,被[a]吃了
包子【2】来了,被[b]吃了
做了两个包子!
包子【3】来了,被[a]吃了
包子【3】来了,被[b]吃了

装饰器

 def login(canshu):
print("已经通过验证")
return canshu
def tv():
print("%s已经进入tv模式")
tv=login(tv)
tv()

装饰器

运行代码:
已经通过验证
%s已经进入tv模式

 a=[[x for x in range(4)] for y in range(4)]
for i in a:print(i)
jishu2=0
for jishu1 in range(4):
jishu2=jishu1+1
for jishu2 in range(jishu2,4):
a[int(jishu1)][int(jishu2)],a[int(jishu2)][int(jishu1)]=a[int(jishu2)][int(jishu1)],a[int(jishu1)][int(jishu2)]
print("\n")
for y in a:print(y)

二维数组旋转90度

运行代码:

[0, 1, 2, 3]
[0, 1, 2, 3]
[0, 1, 2, 3]
[0, 1, 2, 3]

[0, 0, 0, 0]
[1, 1, 1, 1]
[2, 2, 2, 2]
[3, 3, 3, 3]

递归:

 def digui(arg1,arg2,jieshu3):

     arg3=arg1+arg2
if arg1==0:
print(arg1,arg2,end=' ')
print(arg3,end=" ")
if jieshu3>arg3:
return digui(arg2,arg3,jieshu3)
return
digui(0,1,30)

递归

运行代码:
0 1 1 2 3 5 8 13 21 34

正则表达式:

 import re
f=re.sub("\d+","#","d12li3weig4u444o5555g&g66666&6EFss",count=5)
if f:
print(f) f1=re.match("[0-9]{0,10}","4334ge4325ftt&^%kjf35")
if f1:
print(f1.group()) f2=re.findall("[0-9]{1,10}","4334ge4325asdfa&*%ff35")
if f1:
print(f2) f3=re.findall("[a-zA-Z]+","4334ge4325asdfa&*%ff35")
if f1:
print(f3) f4=re.findall("[*]+","4334ge4**325asdfa&*%ff35")
if f1:
print(f4)

正则表达式

运行代码:

d#li#weig#u#o#g&g66666&6EFss
4334
['4334', '4325', '35']
['ge', 'asdfa', 'ff']
['**', '*']

匹配格式
模式描述
^匹配字符串的开头
$匹配字符串的末尾。
.匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
[...]用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k'
[^...]不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。
re*匹配0个或多个的表达式。
re+匹配1个或多个的表达式。
re?匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
re{ n}
re{ n,}精确匹配n个前面表达式。
re{ n, m}匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式
a| b匹配a或b
(re)G匹配括号内的表达式,也表示一个组
(?imx)正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。
(?-imx)正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。
(?: re)类似 (...), 但是不表示一个组
(?imx: re)在括号中使用i, m, 或 x 可选标志
(?-imx: re)在括号中不使用i, m, 或 x 可选标志
(?#...)注释.
(?= re)前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。
(?! re)前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功
(?> re)匹配的独立模式,省去回溯。
\w匹配字母数字
\W匹配非字母数字
\s匹配任意空白字符,等价于 [\t\n\r\f].
\S匹配任意非空字符
\d匹配任意数字,等价于 [0-9].
\D匹配任意非数字
\A匹配字符串开始
\Z匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。c
\z匹配字符串结束
\G匹配最后匹配完成的位置。
\b匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
\B匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
\n, \t, 等.匹配一个换行符。匹配一个制表符。等
\1...\9匹配第n个分组的子表达式。
\10匹配第n个分组的子表达式,如果它经匹配。否则指的是八进制字符码的表达式。
  
正则表达式常用5种操作
re.match(pattern, string)     # 从头匹配
re.search(pattern, string)    # 匹配整个字符串,直到找到一个匹配
re.split()            # 将匹配到的格式当做分割点对字符串分割成列表
上一篇:《转》python学习(11)-表达式和语句


下一篇:ASP.NET集成模式下的管道事件