python 学习第四天

1.迭代器&生成器

2.装饰器

   1.基本装饰器

   2.多参数装饰器(了解)

3.递归

4.算法基础:二分查找,二维数组转换,冒泡排序

5.正则表达式

迭代器&生成器

迭代器

迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,知道所有的元素都被访问结束。 迭代器只能往前不会后退, 另外,迭代器的一个大优点是不要求实现准备好整个迭代过程中所有的元素。迭代器仅仅在迭代到某个元素时才计算该元素。这个特性使 迭代器特别适用于便利一些巨大的或是无限的结合, 比如说几个G的日志文件。

特点:

1. 访问者不需要关心一个迭代器内部的结构,仅需要通过next()方法不断去取下一个内容

2.不能随机访问集合中的某个值,只能从头到尾依次访问

3.访问时不能回退

4.便于循环比较大的数据集合,节省内存。

生成一个迭代器如下:

>>> a = iter([1,2,3,4,5,6,7,8])
>>> a.__next__
<method-wrapper ‘__next__‘ of list_iterator object at 0x02ED0CF0>
>>> a.__next__()
1
>>> a.__next__()
2
>>> a.__next__()
3
>>> a.__next__()
4
>>> a.__next__()
5
>>> 

注:迭代器不能随意访问集合中的某一个值,只能从头到尾依次访问,且访问时不能回退

生成器generator:

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

代码如下:

def test_cash(abc):
    while abc>=0:
        abc -= 100
        yield 100
        print(‘又来取钱了‘)

abc = test_cash(500)

print(abc.__next__())
print(abc.__next__())
print(abc.__next__())
print(‘中断一会,休息一下‘)
print(abc.__next__())

作用:这个yield的主要效果,就是可以中断函数运行状态,并保持中断状态,中断后, 代码可以继续往下执行,过一段时间后,还可以重新调用这个函数,从上次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‘)
    C1 = consumer(‘B‘)
    C.__next__()
    C1.__next__()
    print(‘我要开始做包子啦‘)
    for i in range(10):
        time.sleep(1)
        print(‘%s 做了两个包子‘%name)
        C.send(i)
        C1.send(i)
producer(‘test‘)

装饰器:

python装饰器见另一片文档。

递归

特点

递归算法是一种直接或者间接地调用自身方法的过程,它往往使算法的描述简介而且易于理解。

递归算法解决问题的特点::

(1) 递归就是在过程或函数里调用自身。

(2)在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口

(3)递归算法截图通常显得很间接,但递归算法结题的运行效率极低,所以一般都不提倡用递归算法设计程序。

   在递归调用的过程当中系统为每一层的返回点、局部变量等开辟了栈来存储。递归次数过程容易造成栈溢出等, 所以一般都提倡用递归算法设计程序。

要求

递归算法所体现的“重复” 一般有三个要求:

一是每次调用都在规模上都有所缩小(通常都是减半)

二是相邻两次重复之间有紧密的联系, 前一次要为后一次做准备(通常前一次的输出是为后一次的输入做铺垫)

三是在问题的规模极小时而不再进行递归调用,因而每次递归调用都是有条件的, 无条件出口的递归调用最后会陷入死循环。

示例代码如下:

在数据量比较大的情况下通过二分法查找某个数据

def searchdate(data_result,find_n):
    mid = int(len(data_result)/2)
    if len(data_result) >1:
        if find_n < data_result[mid]:
            print(‘find_n in [mid] left‘)
            searchdate(data_result[:mid],find_n)
        elif find_n > data_result[mid]:
            print(‘find_n in [mid] right‘)
            searchdate(data_result[mid:],find_n)
        else:
            print(‘find date in data_result [%s]‘ %data_result[mid])
if __name__ == ‘__main__‘:
    dabc = list(range(1,99999))
    searchdate(dabc,57668)

通过二分算法我们可以很快的实现数据查找, 特别是在数据量比较大的情况下, 效果会更好。

算法基础

1.生成一个4*4的二维数组并将其瞬时旋转90度

# 生成一个二维数组date = [[aaa for aaa in range(4)] for bbb in range(4)]name = ‘打印‘result = name.center(30, ‘*‘)for i in date:    print(i)for r_index, row in enumerate(date):  # 循环遍历数组,并获取第一层的数组下标    for c_index in range(r_index, len(row)):  # 根据第一层的下标,获取第二层        tmp = date[c_index][r_index]  # 将要交换的元素先存到临时变量中        date[c_index][r_index] = row[c_index]  # 元素交换        date[r_index][c_index] = tmpprint(result)

for r in date:    print(r)
##################另外一种写法##################
data = [[aaa for aaa in range(4)] for bbb in range(4)]for i in range(data.__len__()):    for k in range(data.__len__()):        if (i>k):            temp = data[i][k]            data[i][k]= data[k][i]            data[k][i]=temp

for i in data:    print(i)

ps:对于第一种写法目前还是不太能理解,后期需要在看一遍视频,加深一下

2. 斐波那契数列算法:

简单的来说斐波那契数列就是第三个数值等于第一个数值+第二个数值之和,如下:

1 2 3 5 8 13 21 34 ....

示例代码如下:

def calr(arg1,arg2,stop):
    if arg1 == 0:
        print(arg1,arg2)
    arg3 = arg1 + arg2
    print(arg3)
    if arg3 <stop:
        calr(arg2,arg3,stop)

calr(0,1,789)

3.冒泡排序

将一个不规则的数组按从小到大的顺序进行排序

代码如下:

data = [10,4,33,21,54,3,8,11,5,22,2,1,17,13,6]
 
print("before sort:",data)
 
previous = data[0]
for j in range(len(data)):
    tmp = 0
    for i in range(len(data)-1):
        if data[i] > data[i+1]:
            tmp=data[i]
            data[i] = data[i+1]
            data[i+1] = tmp
    print(data)
 
print("after sort:",data)

################另外一种写法###################
data = [11, 1231, 124, 24123, 554, 632, 591, 112, 109, 889, 100]print(‘before sort:‘, data)for i in range(len(data)):    for k in range(i):        if data[i] < data[k + 1]:            data[i], data[k + 1] = data[k + 1], data[i]print(‘after sort:‘, data)

正则表达式 

语法:

import re
‘‘‘生成要匹配的正则对象,^代表从头开始[0-9]代表匹配0至9的任意一个数字,
# 所以这里的意思是对传进来的字符串进行匹配,如果这个字符串的开头第一个字符是数字,就代表匹配上了‘‘‘
p = re.compile("^[0-9]")
‘‘‘按上面生成的正则对象 去匹配 字符串, 如果能匹配成功,这个m就会有值, 否则m为None<br><br>if m: #不为空代表匹配上了‘‘‘
m = p.match(‘14534Abc‘)
print(m.group())也可以合并到一行来写:= p.match("^[0-9]",‘14534Abc‘)效果是一样, 去别是一个第一种方式需要先对正则进行编译,然后再去做匹配,第二种写法是每次执行的时候,都需要进行便宜如果数据量较大的情况下,建议使用第一种写法, 这样会提高性能。

匹配格式

模式 描述
^ 匹配字符串的开头
$ 匹配字符串的末尾。
. 匹配任意字符,除了换行符,当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)  # 匹配整个字符串,直到找到一个匹配

import re
p = re.compile("[0-9]")
m = p.search("asdja21skdjl")
print(m.group())

re.split()#将匹配到的格式当做分隔点对字符串分割成列表

代码如下:

import re
p = re.compile("[0-9]")
m = p.split("testL1testM2testC")
print(m)

re.findall()# 找到所有要匹配的字符并返回列表格式

import re
p = re.compile("[0-9]")
m = p.findall("asdja21skdjlasdlajd1lajd 2 sadkljsal3 jalksjd2")
print(m)输出如下:[‘2‘, ‘1‘, ‘1‘, ‘2‘, ‘3‘, ‘2‘]

re.sub(self, repl, string, count=0)    # 替换匹配到的字符

import re
p = re.compile("[0-9]")
m = p.sub("&","asdja21skdjlasdlajd1lajd 2 sadkljsal3 jalksjd2",count=5)
print(m)

正则表达式实例

字符匹配

实例 描述
python 匹配 "python".

字符类

实例 描述
[Pp]ython 匹配 "Python" 或 "python"
rub[ye] 匹配 "ruby" 或 "rube"
[aeiou] 匹配中括号内的任意一个字母
[0-9] 匹配任何数字。类似于 [0123456789]
[a-z] 匹配任何小写字母
[A-Z] 匹配任何大写字母
[a-zA-Z0-9] 匹配任何字母及数字
[^aeiou] 除了aeiou字母以外的所有字符
[^0-9] 匹配除了数字外的字符

特殊字符类

实例 描述
. 匹配除 "\n" 之外的任何单个字符。要匹配包括 ‘\n‘ 在内的任何字符,请使用象 ‘[.\n]‘ 的模式。
\d 匹配一个数字字符。等价于 [0-9]。
\D 匹配一个非数字字符。等价于 [^0-9]。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\w 匹配包括下划线的任何单词字符。等价于‘[A-Za-z0-9_]‘。
\W 匹配任何非单词字符。等价于 ‘[^A-Za-z0-9_]‘。

时间: 2024-10-23 02:16:27

python 学习第四天的相关文章

python学习第四十八天json模块与pickle模块差异

在开发过程中,字符串和python数据类型进行转换,下面比较python学习第四十八天json模块与pickle模块差异. json 的优点和缺点 优点  跨语言,体积小 缺点 只能支持 int str list tuple dict pickle 的优点和缺点 优点 专门为python设计,支持python所有的数据类型 缺点 只能python使用,存储数据占空间大 文章来自 www.96net.com.cn 原文地址:https://www.cnblogs.com/96net/p/97806

Python学习第四天学习写的小案例(主要是针对 分支/循环的学习)

Python学习第四天学习写的小案例 (2019/07/17) 第一题:使用while循环输出1 2 3 4 5 6 8 9 10 程序代码: s = 0 while s<10: if s==6: s += 1 # 当数字为7的时候输出一个空格出来 print(end=' ') continue s += 1 print(s,end=' ') 运行结果: 1 2 3 4 5 6 8 9 10 第二题: 求1-100的所有数的和 程序代码: count = 0 for i in range(101

python学习-第四天补充-面向对象

python学习-第四天补充-面向对象 python 私有 --name mangling(名字修改.名字) 在命名时,通过使用两个下划线作为开头,可以使得这个变量或者函数编程私有的,但是这个其实的python的伪私有,实际是python通过名字修改来进行的,python会把这样命名的变量或者函数名改为_类名__变量名 class A: __name="hello" t = A(); #print(t.__name) #这样会出现错误,错误提示说这个变量没有__name类型 print

我的python学习--第四天

一.首先是对前三天的学习内容进行复习 1.python基础的数据结构 数字(int/float,包括整数和浮点数) 布尔(boolean => True/False) 字符串(str,使用''或""括起来) 列表(list) 列表是使用[]括起来的一组数组,在内存中是连续的,可以对其增删改查 字典(dict) 字典是使用{}括起来的k/v键值对,经过哈希计算随机分布在内存中,是无序的,可以对其增删改查 元组(tuple) 元组与列表类似,不同之处在于元组的元素不能修改,元组使用小

Python学习(四)cPickle的用法

python中有两个类似的:pickle与cPickle:两者的关系:“cPickle – A faster pickle” pickle模块中的两个主要函数是dump()和load().dump()函数接受一个文件句柄和一个数据对象作为参数,把数据对象以特定的格式保存到给定的文件中.当我们使用load()函数从文件中取出已保存的对象时,pickle知道如何恢复这些对象到它们本来的格式. cPickle可以对任意一种类型的python对象进行序列化操作,比如list,dict,甚至是一个类的对象

Python学习十四:filter()

Python 中内置了filter()函数用于过滤序列. 用法: filter()接收一个函数和一个序列.filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素. demo: 1.在一个list中,删掉偶数,只保留奇数: #filter odd number in the list def is_odd(n): return n % 2 == 1 print filter(is_odd , [1 , 2 , 3 , 4 , 5 , 6 , 9

Python 学习第四弹:编码问题(转载)

关于python的编码问题一直以来不得解,终于在今天从这篇博文中明白了. 原文地址: http://nedbatchelder.com/text/unipain.html 译文地址:http://pycoders-weekly-chinese.readthedocs.org/en/latest/issue5/unipain.html 译者: yudun1989 实用Unicode编程指南 这是我在 Pycon2012 所做的演讲.你可以阅读本页的幻灯片和文字,或者直接在浏览器中打开 演示 ,或者

Python学习笔记(四)

一.list创建 list 是Python语言中一种内置的数据类型 list 中可以存放不同类型的数据 list = []  #创建一个空列表 list = [1,2,3] #创建一个非空列表,并初始化其元素为1,2,3 二.list长度 使用 len(list_变量) 可以测得list的长度 三.list切片 list = [1,2,3,4,5,6,7,8,9,10] print(list[3:])  #4,5,6,7,8,9,10 print(list[3:5]) #4,5 print(li

python学习笔记(四):函数

一.函数是什么? 函数一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不同的,编程中的函数在英文中也有很多不同的叫法.在BASIC中叫做subroutine(子过程或子程序),在Pascal中叫做procedure(过程)和function,在C中只有function,在Java里面叫做method. 定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可. 二.使用函数的好处: 1.简化代码2.提高代码的复用性3.代码可扩展 三.p

迭代器与函数Python学习(四)

1.1 迭代器: 迭代的工具 1.1.1 什么是迭代: 指的是一个重复的过程,每一次重复称为一次迭代,并且每一次重复的结果是下一次重复的初始值 while True: print('=====>') l=['a','b','c'] count=0 while count < len(l): print(l[count]) count+=1   1.1.2 为什么要有迭代器? 对于序列类型:str,list,tuple,可以依赖索引来迭代取值, 但是对于dict,set,文件,python必须为