生成器函数
生成器有两种,分别是生成器函数和生成器表达式
生成器函数 - yield
- 定义 :含有yield语句的函数为生成器,该函数被调用会返回一个生成器对象。
- 表达式 : yield 表达式
- 用法 :
- yield表达式用于def函数中,目的是将此函数作为生成器使用。
def myinteger(n):
i = 0
while i < n:
yield i
i += 1
for x in myinteger(3):
print(x) #结果为0,1,2
- yield用于生成数据,供迭代器的next()函数使用。
与return的区别
- yield与return相似,后边跟返回值。但是不同的是:会保留执行状态,下次调用next()方法继续执行,从yield的下一条语句开始执行。如下代码所示:
#代码1
# 此示例示意用生成器函数生成一定范围内的自然数
def myinteger(n):
i = 0
while i < n:
yield i
i += 1
f = myinteger(3)
print(next(f)) #0
print(next(f)) #1
print(next(f)) #2
print(next(f)) #StopIteration
- return 返回一个值之后,会直接终止程序的执行,终止当前生成器,如果执行next()会报错(若return之后无参数则不能与yield同时出现在一个函数中,否则为非法编程)。如下代码所示:
def myinteger(n):
i = 0
while i < n:
yield i #此时生成器生成自然数0
i += 1
return i #终止生成器生成自然数,终止程序
f = myinteger(3)
print(next(f)) #0 (因生成器中生成自然数0,故可调用)
print(next(f)) #StopIteration 1 (生成器已被Return终止,故会报错)
生成器表达式
语法
(表达式 for 变量 in 可迭代对象 [if 真值表达式 ])
其中if表达式可以省略
作用
用推导式的形式生成一个新的生成器
L = [1,2,3,4]
gen = (i**2 for i in L) #生成新的生成器
L2 = iter(gen) #生成可迭代对象
print(next(L2)) #1
print(next(L2)) #4
正则表达式之match与search区别
match匹配从第一个字符串开始匹配到的内容
import re
obj = re.match(r'foo','foo,food on the table')
print(obj)#<_sre.SRE_Match object; span=(0, 3), match='foo'>
print(obj.group())#foo
search匹配第一个满足表达式的字符串
obj = re.search(r'foo','fo,food on the table')
print(obj)#<_sre.SRE_Match object; span=(3, 6), match='foo'>
print(obj.group())#foo
注意:两者返回的都是match对象,需要通过goup()方法获取匹配到的内容
正则表达式re.search和re.findall的区别
- re.findall(pattern,string)
作用:根据正则表达式匹配目标字符串的内容
返回值:满足正则表达式条件的所有内容组成的列表;如果正则表达式有子组,则返回子组列表 - re.search(pattern,string)
返回值:匹配第一个满足表达式的match对象,需要通过goup()方法获取匹配到的字符串
代码如下:
import re
l = re.findall(r'\S','Hi I like you')
print(l)#['H', 'i', 'I', 'l', 'i', 'k', 'e', 'y', 'o', 'u']
l = re.search(r'\S','Hi I like you')
print(l.group()) #H
map函数
- 概念:map(func,*iterable) 用函数和可迭代对象中的每个元素作为参数生成新的可迭代对象
- 用法
def power1(x):
return x**2
l = map(power1,range(1,10))
for i in l:
print(i,end=" ") #1 4 9 16 25 36 49 64 81
lambda 函数
- 语法:lamdda[参数1,参数2 …]:表达式
- 作用:创建一个匿名函数对象
- 用法:
myadd = lambda x,y:x+y
print("20+30=",myadd(20,30)) #20+30= 50
-
filter函数。此时lambda函数用于指定过滤列表元素的条件。例如filter(lambda x: x % 3 == 0, [1, 2, 3])指定将列表[1,2,3]中能够被3整除的元素过滤出来,其结果是[3]。
-
sorted函数。此时lambda函数用于指定对列表中所有元素进行排序的准则。例如sorted([1, 2, 3, 4, 5, 6, 7, 8, 9], key=lambda x: abs(5-x))将列表[1, 2, 3, 4, 5, 6, 7, 8, 9]按照元素与5距离从小到大进行排序,其结果是[5, 4, 6, 3, 7, 2, 8, 1, 9]。
-
map函数。此时lambda函数用于指定对列表中每一个元素的共同操作。例如map(lambda x: x+1, [1, 2,3])将列表[1, 2, 3]中的元素分别加1,其结果[2, 3, 4]。
-
reduce函数。此时lambda函数用于指定列表中两两相邻元素的结合条件。例如reduce(lambda a, b: ‘{}, {}’.format(a, b), [1, 2, 3, 4, 5, 6, 7, 8, 9])将列表 [1, 2, 3, 4, 5, 6, 7, 8, 9]中的元素从左往右两两以逗号分隔的字符的形式依次结合起来,其结果是’1, 2, 3, 4, 5, 6, 7, 8, 9’。
原文:https://blog.csdn.net/zjuxsl/article/details/79437563
深拷贝与浅拷贝
浅拷贝
浅拷贝是指创建一个新的对象,其内容是对原对象的引用。(即只拷贝组合对象,不拷贝子对象)
从下方例子可以看出,a和b指向内存中不同的list对象,但他们的元素指向相同的int对象,即子对象。
>>> a = [1,2,3]
>>> b = list(a)
>>> b
[1, 2, 3]
>>> id(a)
139644786708168
>>> id(b)
139644786741704
>>> for x,y in zip(a,b):
... print(id(x),id(y))
...
10919424 10919424
10919456 10919456
10919488 10919488
浅拷贝的特点:两对象内存地址不同,内容相同。
浅拷贝的操作:切片操作,工厂函数,对象的copy()方法,copy模块中的copy()函数。
深拷贝
深拷贝是指拷贝一个新对象,递归拷贝原对象中的子对象
深拷贝只有一个方法:copy模块中的deepcopy()函数
当子对象为不可变类型时(int,str,float,tuple)
>>> a = [1,2,3]
>>> import copy
>>> b = copy.copy(a)
>>> c = copy.deepcopy(a)
>>> id(b)
139644786771144
>>> id(c)
139644786741704
>>> for x,y in zip(a,b):
... print(id(x),id(y))
...
10919424 10919424
10919456 10919456
10919488 10919488
>>> for x,y in zip(a,c):
... print(id(x),id(y))
...
10919424 10919424
10919456 10919456
10919488 10919488
>>> b[0] = 10
>>> b
[10, 2, 3]
>>> a
[1, 2, 3]
>>> c[0] = 11
>>> c
[11, 2, 3]
>>> a
[1, 2, 3]
>>> for x,y in zip(a,c):
... print(id(x),id(y))
...
10919424 10919744
10919456 10919456
10919488 10919488
>>> for x,y in zip(a,b):
... print(id(x),id(y))
...
10919424 10919712
10919456 10919456
10919488 10919488
当对b[0]进行赋值时,因为int为不可变对象,所以需要开辟另一块内存空间创建一个新对象并进行初始化,使b[0]指向该对象。
当子对象为可变对象时(list,dict)
>>> a = [[1,2],[2,3]]
>>> b = copy.copy(a)
>>> c = copy.deepcopy(a)
>>> for x,y in zip(a,b):
... print(id(x),id(y))
...
139644786771464 139644786771464
139644786771400 139644786771400
>>> for x,y in zip(a,c):
... print(id(x),id(c))
...
139644786771464 139644786771144
139644786771400 139644786771144
>>> id(c)
139644786771144
总结:
- 赋值:拷贝生成的对象与原对象内存地址相同,内容也相同,即共用一个内存空间
- 浅拷贝:拷贝生成的对象内存地址相同,与原对象共享内存中的子对象
- 深拷贝: 生成新的组合对象,同时递归地拷贝所有子对象。新的组合对象与原对象没有任何关联。虽然会共享不可变子对象,但仍然相互独立。