Python(二)

本文详细介绍了Python中的序列类型,包括列表、元组和字符串的操作,如加法、乘法、拼接、增量赋值等。接着探讨了字典的创建、增删改查方法,以及字典的嵌套和推导式。此外,还讲解了集合的创建、内置函数、不可变集合和可哈希的概念。最后,文章深入讨论了Python函数的定义、参数、作用域、闭包、装饰器以及匿名函数(lambda)等概念,展示了函数在实际编程中的广泛应用。
摘要由CSDN通过智能技术生成


前言

提示:这里可以添加本文要记录的大概内容:

python第二部分知识介绍


一、序列

可变序列列表、字典
不可变序列元组、字符串
加法和乘法可以用于序列
对于可变序列,对序列进行拼接和增量赋值的时候唯一标识的整数值(id)不会变,但是对于不可变序列,id会改变

>>> s = [1,2,3]
>>> id(s)
1508583974720
>>> s *= 2
>>> s
[1, 2, 3, 1, 2, 3]
>>> id(s)
1508583974720
>>> t = (1,2,3)
>>> id(t)
1508584193728
>>> t *= 2
>>> id(t)
1508584436256

python提供is 和not is 检测对象的id是否相等,然后判断是否是同一个对象。
in 和 not in判断包含问题
del可以删除序列,也可以删除可变序列的某个元素,切片操作也可以完成这种操作
除此之外,del可以跳着清空元素

>>> x = [1,2,3,4,5]
>>> del x[1:4]
>>> x
[1, 5]
>>> y = [1,2,3,4,5]
>>> y[1:4] = []
>>> y
[1, 5]
>>> y = [1,2,3,4,5]
>>> del y[::2]
>>> y
[2, 4]

序列的一些函数

列表、元组、字符串相互转换list(),tuple(),str()
min()返回最小值,max()返回最大值
len()计算长度,sun()求和
sorted()排序,返回全新列表,原列表不会改变reversed()翻转
sorted()可以传入一个key参数,根据ket进行排序

>>> s = ["Apple","Banana","Canada","Fish","Pen"]
>>> sorted(s)
['Apple', 'Banana', 'Canada', 'Fish', 'Pen']
>>> sorted(s, key=len)
['Pen', 'Fish', 'Apple', 'Banana', 'Canada']

all() 函数和any()函数
all()判断是否可迭代对象中所有元素都为真
any()元素判断是否有一个元素为真
enumerate()函数用于返回已给枚举对象,他的功能是将可迭代对象中的每个元素及从0开始的序号共同构成一个二元组的列表,可以指定开始值

>>> seasons = ["Spring","Summer","Fall","Winter"]
>>> enumerate(seasons)
<enumerate object at 0x0000015F3E85C580>
>>> list(enumerate(seasons))
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
>>> list(enumerate(seasons,10))
[(10, 'Spring'), (11, 'Summer'), (12, 'Fall'), (13, 'Winter')]

zip()函数用于创建一个聚合多个可迭代对象的迭代器。它会将作为参数传入发每个可迭代对象的每个元素依次组合成为元组,即第i个元组包含来自每个参数的第i个元素。如果参数的长度不同,会取最短的长度
如果不想丢弃,可以使用itertools的zip_longest()函数,此处不再介绍-

>>> x = [1,2,3]
>>> y = [4,5,6]
>>> z= zip(x,y)
>>> list(z)
[(1, 4), (2, 5), (3, 6)]
>>> p = [7,8,9]
>>> z = zip(x,y,p)
>>> list(z)
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
>>> p = "happy"
>>> z = zip(x,y,p)
>>> list(z)
[(1, 4, 'h'), (2, 5, 'a'), (3, 6, 'p')]

map()会根据提供的函数对指定的可迭代对象的每个元素进行运算,并将返回运算结果的迭代器。

>>> c = map(ord,"Fishc")
>>> list(c)
[70, 105, 115, 104, 99]
>>> c = map(pow,[1,2,3],[4,5,6])
>>> list(c)
[1, 32, 729]

fliter()函数会根据提供的函数对指定的可迭代对象的每个元素进行运算,并将运算结果为真的元素,以迭代器的形式返回。

>>> list(filter(str.islower,"Fishc"))
['i', 's', 'h', 'c']

迭代器和可迭代对象
迭代器是可迭代对象
可迭代对象可以重复使用
迭代器是一次性的
iter()可以把可迭代对象变为迭代器,next可以每次从迭代器中拿出一个元素

>>> x = [1,2,3,4,5]
>>> y = iter(x)
>>> type(x)
<class 'list'>
>>> type(y)
<class 'list_iterator'>
>>> next(y)
1
>>> next(y)
2
>>> next(y)
3
>>> next(y)
4
>>> next(y)
5
>>> next(y)
Traceback (most recent call last):
  File "<pyshell#232>", line 1, in <module>
    next(y)
StopIteration

如果不想抛出异常,可以在next后面加一个参数next(y,“没有啦”)
当迭代器中没有元素的时候,他就会输出“没有啦”

二、字典

1.定义

字典是映射关系,key和value一一对应
通过指定一个key可以创建字典的一个值
使用dict函数创建字典
使用列表作为参数
zip函数也可以创建dict

>>> a = {"one":"1","two":"2","three":"3"}
>>> b= dict(one = "1", two = "2", three="3")
>>> c = dict([("one","1"),("two","2"),("three","3")])
>>> d = dict(zip(["one","two","three"],["1","2","3"]))
>>> a == b == c ==d
True

2.增删改查


  • fromkeys()方法可以创建一个新字典
>>> d = dict.fromkeys("fishc",70)
>>> d
{'f': 70, 'i': 70, 's': 70, 'h': 70, 'c': 70}
>>> d['f']=1
>>> d
{'f': 1, 'i': 70, 's': 70, 'h': 70, 'c': 70}
>>> d['g']=6
>>> d
{'f': 1, 'i': 70, 's': 70, 'h': 70, 'c': 70, 'g': 6}

序列中元素可以重复,但是字典key不会重复


  • pop(key)可以删除对应的key和value
    popitem()在python3.7之后是删除最后一个加入字典键值对
    del 也可以删除指定的关键字也可以删除整个字典
    只想清除字典的内容,可以用clear,字典会变成空字典
  {'f': 1, 'i': 70, 's': 70, 'h': 70, 'c': 70, 'g': 6}
>>> d.pop('f')
1
>>> d
{'i': 70, 's': 70, 'h': 70, 'c': 70, 'g': 6}
>>> d.popitem()
('g', 6)
>>> d
{'i': 70, 's': 70, 'h': 70, 'c': 70}
>>> del d['i']
>>> d
{'s': 70, 'h': 70, 'c': 70}
>>> del d
>>> d
Traceback (most recent call last):
  File "<pyshell#257>", line 1, in <module>
    d
NameError: name 'd' is not defined

  • update()可以直接传入一个键值对,也可以传入包含键值对的可迭代对象
>>> d = dict.fromkeys("fishc",70)
>>> d.update({'i':105,'s':110})
>>> d
{'f': 70, 'i': 105, 's': 110, 'h': 70, 'c': 70}
>>> d.update(f = 60,c=66)
>>> d
{'f': 60, 'i': 105, 's': 110, 'h': 70, 'c': 66}

  • 可以直接查找,也可以使用get函数,setdefault()查找一个key,要是没有直接创建
>>> d
{'f': 60, 'i': 105, 's': 110, 'h': 70, 'c': 66}
>>> d.get('c',"没有啦")
66
>>> d.get('C',"没有啦")
'没有啦'
>>> d.setdefault('c','code')
66
>>> d.setdefault('C','code')
'code'
>>> d
{'f': 60, 'i': 105, 's': 110, 'h': 70, 'c': 66, 'C': 'code'}

items(),keys(),values()
上面三个函数的结果会跟随字典的值动态变化

>>> keys = d.keys()
>>> values = d.values()
>>> items = d.items()
>>> keys
dict_keys(['f', 'i', 's', 'h', 'c', 'C'])
>>> values
dict_values([60, 105, 110, 70, 66, 'code'])
>>> items
dict_items([('f', 60), ('i', 105), ('s', 110), ('h', 70), ('c', 66), ('C', 'code')])
>>> d.pop('C')
'code'
>>> keys
dict_keys(['f', 'i', 's', 'h', 'c'])
>>> values
dict_values([60, 105, 110, 70, 66])
>>> items
dict_items([('f', 60), ('i', 105), ('s', 110), ('h', 70), ('c', 66)]

字典也提供copy()函数实现对字典浅拷贝

3.其他一些函数

list可以把字典的key或者value变为列表
iter也可以应用在字典上
reversed可以对字典内部的键值对进行逆向操作

>>> list(d)
['f', 'i', 's', 'h', 'c']
>>> list(d.values())
[60, 105, 110, 70, 66]
>>> e = iter(d)
>>> next(e)
'f'
>>> next(e)
'i'
>>> next(e)
's'
>>> next(e)
'h'
>>> next(e)
'c'
>>> next(e)
Traceback (most recent call last):
  File "<pyshell#297>", line 1, in <module>
    next(e)
StopIteration

4.字典的嵌套及推导式

字典可以嵌套字典,也可以嵌套列表

>>> d = {"A":{"语文":70,"数学":80},"B":{"语文":90,"数学":90}}
>>> d['A']['语文']
70
>>> d = {"A":[70,80],"B":[90,90]}
>>> d['A'][0]
70

推导式也可以加入筛选条件
没有元组推导式,生成的最后是一个生成器
如果想要把两个列表生成字典,必须使用zip函数或者range函数对列表进行迭代,不然会出现意想不到的效果。

>>> d = {'f': 60, 'i': 105, 's': 110, 'h': 70, 'c': 66, 'C': 'code'}
>>>> b = {v:k for k,v in d.items()}
>>> b
{60: 'f', 105: 'i', 110: 's', 70: 'h', 66: 'c', 'code': 'C'}
>>> [(x,y) for x in [1,2,3] for y in [4,5,6]]
[(1, 4), (1, 5), (1, 6), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6)]
>>> {x:y for x in [1,2,3] for y in [4,5,6]}
{1: 6, 2: 6, 3: 6}

三、集合

1.创建

三种方法
花括号、集合推导式、类型构造器

>>> {"FishC","Python"}
{'Python', 'FishC'}
>>> { s for s in "FishC"}
{'h', 's', 'C', 'F', '
>>> set("FishC")
{'h', 's', 'C', 'F', 'i'}

不可以使用下标的方式访问集合中的元素
但是可以判断集合中是不是存在这个元素
可以使用迭代的方法访问集合中的元素
最重要的是:集合中的元素是无序且唯一的

2.内置函数

copy()函数可以实现集合的浅拷贝
isdisjoint()可以判断两个集合是不是毫不相干
issubset()可以判断某个集合是不是另一个集合的子集
issuperset()可以判断某个集合是不是另一个集合的超集

>>> s = set("FishC")
>>> s.isdisjoint(set(":Python"))
False
>>> s.issubset(set("Fish.com"))
False
>>> s.issubset(set("FishC.com"))
True

除此之外,python还提供多个集合的交集,并集,差集的函数
使用<,<=可以判断是否是真子集和子集
使用>,>=可以判断是否是真超集和超集
并集用| 交集用& 差集用- 对称差集是^

3.不可变集合

frozenset()是不可变集合

>>> t = frozenset("FishC")
>>> t
frozenset({'h', 's', 'C', 'F', 'i'})

使用update对set进行更新
add可以将整个字符串加入集合中
remove()删除元素,元素不存在,报错
discard()删除元素,元素不存在静默处理

>>> s = set("FishC")
>>> s.update([1,1],"23")
>>> s
{1, 'h', 's', '3', 'C', 'F', 'i', '2'}
>>> s.add("45")
>>> s
{1, 'h', '45', 's', '3', 'C', 'F', 'i', '2'}
>>> s.remove(1)
>>> s
{'h', '45', 's', '3', 'C', 'F', 'i', '2'}
>>> s.remove(1)
Traceback (most recent call last):
  File "<pyshell#340>", line 1, in <module>
    s.remove(1)
KeyError: 1
>>> s.discard(1)

4.可哈希

python大多数不可变类型都是可哈希的,可变对象都是不可哈希的
只有可哈希的对象才有资格作为字典的键和集合的元素
想要实现集合的嵌套可以借用frozenset


四. 函数

1. 函数定义

使用 def来定义函数,函数可以有参数,可以有返回值

>>> def myfunc():
	pass

上面是一个最简单的函数,这个函数什么功能都没有实现。

>>> myfunc()
>>> def myfunc():
	for i in range(3):
		print("hello")

		
>>> myfunc()
hello
hello
hello
>>> def myfunc(name):
	for i in range(3):
		print(f"hello {name}!")
		>>> myfunc("world")
hello world!
hello world!
hello world!

上面的函数有了功能,它可以打印一些东西,我们还可以对函数传入参数,不同的参数输出不同的结果。
上面的name是形参,world是实参。
函数可以使用return返回一个结果,不管return在函数的什么位置,只要执行return会直接退出整个函数

>>> def div(x, y):
	if y == 0:
		print("除数不能为0")
		return 
	else:
		return x/y

	
>>> div(3,2)
1.5
>>> div(3,0)
除数不能为0

2. 参数

①.位置参数

python函数的位置参数,直接按照顺序对形参进行传递值,

>>> def myfunc(x, y, z):
	return "".join((x,y,z))

>>> myfunc("我","爱","你")
'我爱你'
>>> myfunc("你","爱","我")
'你爱我'

②. 关键字参数

除此之外,还可以用关键字参数,这样可以不关注参数的位置,在参数很多的情况下比较适用

>>> myfunc(z="你",y="爱",x="我")
'我爱你'

可以看到关键字参数不管传入参数的位置,而是根据形参的名字进行赋值
如果想要关键字参数和位置参数一起使用,位置参数必须在关键字参数之前,在之间也不行

③. 默认参数

函数允许使用默认参数,可以在函数定义的时候就指定默认值,如果调用的时候没有传入实参,那么就采用默认值

>>> def myfunc(x, y, z="world"):
	return "".join((x,y,z))

>>> myfunc("我","爱")
'我爱world'
>>> myfunc("我","爱","你")
'我爱你'

这里需要注意的是,默认参数必须放到最后

限制只能使用位置参数
函数参数中 / 之前的参数只能使用位置参数,后面的可以使用关键字参数也可以不使用
>>> def abc(a, /, b,c):
	print(a,b,c)

	
>>> abc(1,2,3)
1 2 3
>>> abc(3,b=2,c=1)
3 2 1
>>> abc(a=1,b=2,c=3)
Traceback (most recent call last):
  File "<pyshell#43>", line 1, in <module>
    abc(a=1,b=2,c=3)
TypeEr
只能使用关键字参数,利用星号*
左侧可以是位置参数或者关键字参数,但是右边只能是关键字参数,不然会报错
>>> def abc(a, *, b,c):
	print(a,b,c)

	
>>> abc(a=1,b=2,c=3)
1 2 3
>>> abc(1,b=2,c=3)
1 2 3
>>> abc(1,2,3)
Traceback (most recent call last):
  File "<pyshell#48>", line 1, in <module>
    abc(1,2,3)
TypeError: abc() takes 1 positional argument but 3 were given

④. 收集参数,不定长参数

Ⅰ.收集参数打包为元组,使用* ,*args
>>> def myfunc(*args):
	print("有{} 个参数".format(len(args)))
	print("第一个参数是{}".format(args[0]))

	
>>> myfunc("hh","happy")2 个参数
第一个参数是hh
  • 形参 *args 类型是元组tuple,外部调用函数时传递的参数不论是整数还是BOOL值或者是字符串str,实际上传递的都是元组数据;
  • 如果函数形参是不定长参数,外部调用函数传递多个参数时,默认按顺序实参匹配形参,剩余的参数全部作为(元组)不定长参数传递;
  • 如果没有为函数的不定长参数传递参数,默认为空元组();
  • 如果不定长参数后面还有其他参数,必须使用关键字参数指定其他参数,不然会被收集到不定长参数
>>> def abc(*a, b,c):
	print(a,b,c)

	
>>> abc(1,2,3)
Traceback (most recent call last):
  File "<pyshell#61>", line 1, in <module>
    abc(1,2,3)
TypeError: abc() missing 2 required keyword-only arguments: 'b' and 'c'
>>> abc(1,b= 2,c=3)
(1,) 2 3
Ⅱ. 收集参数打包为字典

使用连续两个星号**,**kwargs

  • 形参 **kwargs 类型是字典dict,函数外部调用函数传递参数时需要使用关键字参数,实参写法:a=1,b=2,c=False,d=”hello”;
  • 如果函数形参是不定长参数,外部调用函数传递多个参数时,默认按顺序实参匹配形参,关键字参数全部作为(字典)不定长参数传递;
  • 如果没有为函数的不定长参数传递参数,默认为空字典{};
>>> def myfunc(**kwargs):
	print(kwargs)

	
>>> myfunc(a=1,b=2,c=3)
{'a': 1, 'b': 2, 'c': 3}

函数不定长参数*args和**kwargs只能放在形参的末尾,顺序不能错.

>>> def abc(a, *b,**c):
	print(a,b,c)
>>> abc(1,2,3,4,x=5,y=6)
1 (2, 3, 4) {'x': 5, 'y': 6}

⑤. 解包参数

*和**在形参上使用起到了打包的作用,在实参上使用就是解包的效果
*对元组进行解包,**对字典进行解包

>>> def myfunc(a,b,c,d):
	print(a,b,c,d)

	
>>> myfunc(args)
Traceback (most recent call last):
  File "<pyshell#80>", line 1, in <module>
    myfunc(args)
TypeError: myfunc() missing 3 required positional arguments: 'b', 'c', and 'd'
>>> myfunc(*args)
1 2 3 4
>>> kwargs = {'a':1,'b':2,'c':3,'d':4}
>>> myfunc(**kwargs)
1 2 3 4

3. 作用域

①局部和全局变量

变量定义在函数内,就是局部参数,只能在函数中调用
如果定义在任何函数的外部,就是全局变量,函数内外都可以访问到
要想在函数内部修改全局变量,那么可以使用globa语句

>>> x = 880
>>> def myfunc():
	global x
	x =520
	print(x)
>>> myfunc()
520
>>> x
520

②. 嵌套函数

函数内部可以定义另一个函数
但是这个内部函数在外面是不可以直接调用的,只能通过外部函数进行调用

>>> def funA():
	x =520
	def funB():
		x = 880
		print("In funB, x=",x)
	funB()
	print("In funA, x=",x)

	
>>> funA()
In funB, x= 880
In funA, x= 520

内部函数只能调用外部函数的变量,不能修改。如果想要在内部函数修改外部函数的变量,可以使用nonlocal

>>> def funA():
	x =520
	def funB():
		nonlocal x
		x = 880
		print("In funB, x=",x)
	funB()
	print("In funA, x=",x)

	
>>> funA()
In funB, x= 880
In funA, x= 880

③LEGB规则

Local局部作用域 Enclosed 嵌套函数的外层函数作用域 Global全局作用域 Build-In内置作用域
不要起和内置函数相同的变量名,不然会毁掉内置函数,导致无法调用

4. 闭包

如果想要在外面调用内部函数,需要对外部函数进行修改
将函数作为返回值的时候不需要加小括号,只有在定义和调用的时候需要小括号。

>>> def funA():
	x =520
	def funB():
		print("In funB, x=",x)
	return funB
	print("In funA, x=",x)

	
>>> funA()
<function funA.<locals>.funB at 0x0000020E83CE5DC0>
>>> funA()()
In funB, x= 520

可以看到调用funA函数得到对funB函数的一个引用,在funA后面加小括号就可以调用funB
也可以不使用funA调用funB

>>> f = funA()
>>> f()
In funB, x= 520

对于嵌套函数来说,外层函数的作用域是会通过某种形式保存下来的,尽管这个函数已经调用完了,但是外层作用域会被保存下来(比如赋值给f),不会像局部作用域一样消失。而且借用nonlocal可以修改外部函数的变量

>>> def outer():
	x = 0
	y = 0
	def inner(x1, y1):
		nonlocal x, y
		x += x1
		y += y1
		print("x={},y={}".format(x, y))
	return inner

>>> move = outer()
>>> move(1,2)
x=1,y=2
>>> move(-2,-2)
x=-1,y=0

闭包的一个陷阱!

def my_func(*args):
    fs = []
    for i in xrange(3):
        def func():
            return i * i
        fs.append(func)
    return fs

fs1, fs2, fs3 = my_func()
print fs1()
print fs2()
print fs3()

程序的结果并不是想象中的0,1,4而是4,4,4
这个例子中,my_func返回的并不是一个闭包函数,而是一个包含三个闭包函数的一个list。这个例子中比较特殊的地方就是返回的所有闭包函数均引用父函数中定义的同一个自由变量。

但这里的问题是为什么for循环中的变量变化会影响到所有的闭包函数?尤其是我们上面刚刚介绍的例子中明明说明了同一闭包的不同实例中引用的自由变量互相没有影响的。而且这个观点也绝对的正确。

那么问题到底出在哪里?应该怎样正确的分析这个错误的根源。

其实问题的关键就在于在返回闭包列表fs之前for循环的变量的值已经发生改变了,而且这个改变会影响到所有引用它的内部定义的函数。因为在函数my_func返回前其内部定义的函数并不是闭包函数,只是一个内部定义的函数。
正确的做法便是将父函数的local variable赋值给函数的形参。函数定义时,对形参的不同赋值会保留在当前函数定义中,不会对其他函数有影响。

def my_func():
    fs = []
    for i in range(3):
        def func(_i=i):
            return _i * _i
        fs.append(func)
    return fs

返回闭包中不要引用任何循环变量,或者后续会发生变化的变量。
闭包的优点在于:

  • 局部变量无法共享和长久的保存,而全局变量可能造成变量污染,闭包既可以长久的保存变量又不会造成全局污染。(这些变量的值始终保持在内存中,不会在外层函数调用后被自动清除)
  • 提高代码的可复用性(当变量需要反复使用,又想避免全局污染时)
    缺点:由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,也可能导致内存泄露。

5. 装饰器

除了可以返回函数,函数的参数也可以是函数
一下可以统计函数的运行时间

import time

def time_master(func):
    print("开始")
    start = time.time()
    func()
    end = time.time()
    print("结束")
    print(f"total {(end -start):.3f}秒")

def myfunc():
    time.sleep(2)
    print("hello")

time_master(myfunc)
开始
hello
结束
total 2.002

但是这样每次想要去统计时间的时候都需要去调用time_master这个函数,更好的解决方法是在调用myfunc这个函数的时候它能够自觉的去执行统计时间的函数,这就需要装饰器了。

import time

def time_master(func):
    def call_func():
        print("开始")
        start = time.time()
        func()
        end = time.time()
        print("结束")
        print(f"total {(end -start):.3f}秒")
    return call_func

@time_master
def myfunc():
    time.sleep(2)
    print("hello")

myfunc()

等同于以下写法

import time

def time_master(func):
    def call_func():
        print("开始")
        start = time.time()
        func()
        end = time.time()
        print("结束")
        print(f"total {(end -start):.3f}秒")
    return call_func

def myfunc():
    time.sleep(2)
    print("hello")

t = time_master(myfunc)
t()

装饰器可以在不更改原来函数的前提下,对函数增加功能,如果多人都想在原来的基础上定制自己的函数这样不容易引起冲突。
多个装饰器也可以用在一个函数上面

def add(func):
    def inner():
        x = func()
        return x+1
    return inner

def cube(func):
    def inner():
        x = func()
        return x*x
    return inner

def square(func):
    def inner():
        x = func()
        return x*x*x
    return inner

@add
@cube
@square
def myfunc():
    return 2

print(myfunc())

装饰器的调用顺序是从下往上的
装饰器传递参数
装饰器想要传递参数需要添加一层调用将参数传递进去

import time

def logger(msg):
    def time_master(func):
        def call_func():
            start = time.time()
            func()
            end = time.time()
            print(f"[{msg}]total {(end -start):.3f}秒")
        return call_func
    return time_master

@logger("A")
def funA():
    time.sleep(1)
    print("in A")


@logger("B")
def funB():
    time.sleep(1)
    print("in B")

funA()
funB()

6. lambda表达式(匿名函数)

语法:lambda arg1, arg2, arg3, ... argN : expression
使用传统函数的定义方式如下

def <lambda>(arg1, arg2, arg3, .. argN):
    return expression

lambda表达式可以放在列表里面,也可以在map函数和filter函数中使用

>>> mapped = map(lambda x :ord(x)+10,"FishC")
>>> list(mapped)
[80, 115, 125, 114, 77]

7.生成器

定义生成器在函数中使用yield表达式来替代函数中的return语句

>>> def counter():
	i =0
	while i<5:
		yield i
		i+=1

		
>>> counter()
<generator object counter at 0x0000020E81C37F90>
>>> for i in counter():
	print(i)

	
0
1
2
3
4

counter函数每次调用的时候提供一个数据,每次执行到yield i的时候提供一个数据,暂停并保留状态,下一次调用从i+=1开始执行。
生成器支持next()函数
斐波那契数列闭包和生成器编程:

# 闭包实现
def func():
    x1 = 0
    y1 = 1
    def inner():
        nonlocal x1, y1
        x1, y1 = y1,x1+y1
        return x1
    return inner

def fib():
    x1 = 0
    x2 = 1
    while 1:
        x1, x2 = x2, x1+x2
        yield x1

f = func()
for i in range(10):
    print(f())

f = fib()
for i in range(10):
    print(next(f))

生成器表达式

>>> t = (i**2 for i in range(10))
>>> for i in t:
	print(i)

	
0
1
4
9
16
25
36
49
64
81

8. 递归

递归可以实现函数调用函数本身

>>> def func(n):
	if n == 1:
		return 1
	else:
		return n*func(n-1)

	
>>> print(func(5))
120

但是递归的效率不如迭代

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值