补充:函数不能改变全局不可变的变量,可变变量仍然可改变。
l1 = [1,2]
def a(l1):
l1.pop(1)
a(l1)
print(l1)
生成器
生成器:python社区把生成器与迭代器看成同一种,生成器的本质就是迭代器。唯一的区别是:生成器是我们自己用python代码构建的数据结构,迭代器都是python提供的,或者转化的。
获取生成器的方法:
生成器函数
生成器表达式
python内部提供的。
生成器函数获取生成器,yield:
def func():
print(1)
print(3)
yield 5
print(func) #<function func at 0x000001A3CCA04438> 仍然是一个函数
ret = func()
print(ret) #<generator object func at 0x000002471A631D48>
#generator object#生成器对象
def func():
print(3)
yield 5
ret = func()
print(next(ret)) #3 5
#一个next对一个yield的返回值
def func():
print(3)
yield 5
yield 7
print(next(func())) #3 5
yield与return
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
return:一个函数中只能存在一个return结束函数的调用,并且给函数的执行者返回值。
yield:只要函数中有yield那么它就是生成器函数,生成器函数中可以存在多个yield,一个next对一个yield的返回值,yield不会结束函数的调用,但return会结束函数的调用。
#举例运用:
def func():
for i in range(1000000):
yield i
ret = func()
i = 1000000
while i >= 0:
print(next(ret))
i -= 1
- 6
- 7
- 8
- 9
如果再次调用yield就会接着上次的next.
def func():
for i in range(1000000):
yield i
ret = func()
for i in range(5):
print(next(ret))
for i in range(10):
print(next(ret))
#0, 2,3,4,5,6,7,8,9,10,11,12,13,14
yield from(3.4版本以后):将数据变成一个迭代器返回
def func():
l1 = [1,2,3,4,]
yield l1
print(next(func()))
#[1, 2, 3, 4]
def func():
l1 = [1,2,3,4,]
yield from l1 #将这个列表变成了一个迭代器返回
print(next(func()))
#1
print(nex(func()))
#2
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
生成器函数可以直接用for循环:
def func():
l1 = [1,2,3]
yield from l1
for i in func():
print(i) #1 2 3
列表推导式,生成器表达式:
列表推导式:用一行代码构建一个比较复杂有规律的列表。
l1 = [i for i in range(10)] #可将range换为可迭代对象。
列表推导式可分为两类。
循环模式:需遍历每一个元素。[变量(加工后的变量) for 变量 in iterable]
#例1:将10以内所有整数的平方写入列表:
l1 = [i*i for i in range(11)]
print(l1)
#例2:100以内的所有奇数写入列表:
l1 = [i for i in range(1,100,2)]
print(l1)
#例3:从python1到python10写入列表:
l1 = [f'python{i}' for i in range(1,11)]
print(l1)
- 6
- 7
- 8
- 9
- 10
- 11
筛选模式:[变量(加工后的变量) for 变量 in iterable if 条件]
#例1:将10以内能够被2整除的数写入列表
l1 = [i for i in range(11) if i%2==0]
print(l1)
#例2:过滤列表l1中小于3的字符串,将剩下的转换成大写。l1 = ['nonl','globals','as','in']
l1 = ['nonl','globals','as','in']
l2 = [i.upper() for i in l1 if len(i)>=3]
print(l2)
#例3:将num列表中含有两个0的字符串生成一个新列表。num = [['021','001','201'],['100','012','010']]
l1 = [j for i in num for j in i if j.count('0') == 2]
print(l1)
- 6
- 7
- 8
- 9
- 10
- 11
- 12
生成器表达式:与列表推导式的写法几乎一样,生成器也有循环模式和筛选模式,只是将[]变为()。但比列表推导式更节省空间。
l1 = (i for i in range(10))
print(l1)
#<generator object <genexpr> at 0x000001BB028F8CC8>
print(next(l1)) #0
l1 = (i for i in range(10))
for i in l1: #可直接用for循环,因为for循环本身就是将可迭代对象变为迭代器再循环。
print(i)
- 6
- 7
列表推导式
缺点:
只能构建计较复杂并且有规律的列表;
超过三层循环才能构建成功的,不建议使用列表推导式;
无法找查错误(debug模式)
字典推导式
l1 = ['1','2','3']
l2 = ['一','二','三']
dic = {l1[i]:l2[i] for i in range(len(l1))}
- 1
- 2
- 3
集合推导式
set1 = {i for i in range(10)}
内置函数:
python提供了68个内置函数。
一级难点:abs() enumerate() filter() max() min() open() range() print() len() list() dict() str() float() reversed() set() sum() tuple() type() zip() dir()
二级难点:classmethod() delattr() getattr() issubclass() isinstance() object() property() setattr() staticmethod() super()
三级难点:all() any() bytes() callable() chr() complex() divmod() eval() exec() format() frozenset() globals() hash() help() id() input() int() locals() next() oct() ord() pow() repr() round()
eval():剥去字符串的外衣(引号),运算里面的代码,有返回值。工作时最好不用,容易中病毒。
s1 = ‘1+1’
print(s1) #1+1
print(eval(s1),type(eval(s1))) #2 <class ‘int’>
exec():与eval()几乎一样,但是它是处理代码流的。工作时最好不用,容易中病毒。
msg = """
for i in range(5):
print(i)"""
exec(msg) #0,1,2,3,4
- 1
- 2
- 3
- 4
hash:获取一个对象(可哈希对象:int,str,bool,tuple)的哈希值。
哈希值:加密算法之间需要哈python基础教程希值,与哈希算法有关。
print(hash('12'))
help():打印/获取一个对象的使用方法。
print(help(str))
print(help(str.upper))
callable():判断一个对象是否可调用,真为True,假为False。
l1 = [1,2]
def func():
pass
print(callable(l1)) #False
print(callable(func)) #True
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13