函数
- 常用的功能块编写成函数,放在函数库中供公共使用,内置函数可以直接调用。
- 提高编程效率以及代码重用性,具有特定功能。是结构化设计程序的基础,return返回值返回到函数调用处。
- 函数可以有多个返回值,之间用逗号隔开,返回结果为元组类型。
def func(a,b=1):
return a*b
func(3) # 若不传b,则为默认定义的
# 定义一个遍历
def test(list):
for i in list:
print(i)
if __name__=='__main__':# 测试
list1=[1,2,3,4,5,8,8]
test(list1) # 调用时执行,函数不会在定义时自己执行
函数内部定义的变量在外不可以访问
def test(list):
b=1
print(b) # 出错,不可访问
# 循环可以访问
for i in range(5):
a=12
print(a)
自定义函数的五种参数:
位置参数:x,n实参给形参赋值(计算x的n次方
def fun(x,n):
return x**n
if __name__=='__main__':
print(fun(2,8))#接收返回值
默认参数:在定义形参之初给定值,该形参值经常不变
def fun(name,sex,age=20):
print(name,sex,age)
fun('zhao','G',18)#默认值给定以后也可改
可变参数:(可变长度)以元组方式存储
def fun(*args):
print(args)
fun(1,2,3,4,5,6,7)
关键字参数:允许传入0个或任意个包含参数名的参数
def test(name,age,**other):
print(name,age,other)
dict={'性别':'男','tel':'135********'}
test('zhao',18,**dict)
命名关键字参数,参数需要特殊分割符 星号,星号后面所有参数被视为命名关键字参数 传递参数时sex=‘nv’
def test(name,age,*,sex,email):
print(name,age,sex,email)
test('zhao',18,sex='nv',email='125***')
参数组合方式:位置参数、默认参数、可变参数、命名关键字参数、关键字参数可组合按顺序使用
递归:函数自己调用自己
def func(n):
if n==1:
return 1
return n*func(n-1)
print(func(3))
生成器
什么是生成器
通过列表推导式,可以直接创建一个列表,但是受到内存限制,列表容量肯定是有限的,而且创建一个包含100万个元素的列表,会占用很大的存储空间。如果我们仅仅需要访问前面几个元素,则后面元素的占用存储空间就被浪费,所以,如果列表元素可以按照某种算法算出来,那我们就可以在循环当中不断地推导它,生成元素,这样就不必创建完整的list,从而大大节省了存储空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
函数生成列表
def f(n):
return n ** 3
a = [ f(x) for x in range(10) ] # 生成列表 [0, 1, 8, 27, 64, 125, 216, 343, 512, 729]
函数生成生成器对象
def f(n):
return n ** 3
a = (f(x) for x in range(10)) # 生成生成器对象
# for i in a:
# print(i)
print(next(a)) # 一次拿出一个对象0
yield相当于生成生成器对象,并返回5和2
def foo():
print('xiao')
yield 5
print('pengyou')
yield 2
return None
for i in foo():
print(i) # 输出返回值xiao 5 pengyou 2
斐波那契数列
def fib(max):
n,before,after=0,0,1
while n<max:
print(before)
before,after=after,before+after # 赋值 先计算后赋值
n+=1
fib(5)
斐波那契数列生成器对象
def fib1(max):
n,before,after=0,0,1
while n<max:
yield before # 生成器对象
before,after=after,before+after # 赋值 先计算后赋值
n+=1
g=fib1(5) # 生成器对象
print(next(g))
生成器对象send和next的用法
def bar():
print('ok1')
count = yield 1
print(count) # count为ssss
yield 2
# for i in bar():
# print(i) # ok1 1 None 2
bar = bar()
c = bar.send(None) # 相当于next(bar),若第一个send之前没有next,则必须传参数None,输出ok1。执行到yield 1
print(c) # c 为 1
d = bar.send('ssss') # 执行count =,以及print ssss
print(d) # d 为 2
# 1.bar = bar()程序开始执行以后,因为bar函数中有yield关键字,所以bar函数并不会真的执行,而是先得到一个生成器bar(相当于一个对象)
# 2.直到调用send(None)方法,bar函数正式开始执行,先执行bar函数中的print方法,程序遇到yield关键字,然后把yield想想成return,return了一个1之后,程序停止,并没有执行赋值给count。
# 3.send('ssss')方法,这个时候是从刚才那个send程序停止的地方开始执行的,也就是要执行count的赋值操作,这时候要注意,这个时候赋值操作的右边是ssss(因为刚才那个是return出去了,传递了一个ssss给左边),所以这个时候count赋值是ssss,所以接着下面的输出就是ssss
# 4.最后yield return 2
生成器对象实现多线程
import time
def consumer(name):
print('%s准备吃包子'%name)
while True:
yield # 生成器 一个send函数继续往下走,不然就停留在此等待
print('包子被%s吃了'%name)
def producer(name):
c=consumer('a')
c2=consumer('b')
next(c) # 到yield阻塞
next(c2)
print("%s开始包包子啦~"%name) # 包完包子才可以进行吃包子
for i in range(10):
time.sleep(1)
print("做了两个包子")
c.send(i) # 继续运行print
c2.send(i)
producer("me")
生成随机数字字母
import random
def v_code():
code=""
for i in range(5):
add=random.choice([random.randrange(10),chr(random.randrange(65,91))]) # 返回列表的随机项
print(add)
code+=str(add)
return code
print(v_code())
迭代器
迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。
可迭代对象Iterable:
可以直接作用于for循环的数据类型有以下几种:
一类是集合数据类型,如list、tuple、dict、set、str等;
一类是generator,包括生成器和带yield的generator function。这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。可以使用 isinstance() 判断一个对象是否是 Iterable 对象。
from collections import Iterable
print(isinstance([x for x in range(10)],Iterable)) # True
迭代器Iterator:
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。可以使用isinstance()判断一个对象是否是Iterator对象
from collections import Iterator
print(isinstance([x for x in range(10)],Iterator)) # False
迭代器不一定是生成器,生成器一定是迭代器
凡是可作用于for循环的对象都是Iterable类型;凡是可作用于next()函数的对象都是Iterator类型
集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。
from collections import Iterator
print(isinstance(iter([x for x in range(10)]),Iterator)) # True
如果类中有 iter 方法,创建的对象为可迭代对象
class Foo:
def __init__(self, name,age):
self.name = name
self.age = age
def __iter__(self):
return iter([11,22,33]) # 可迭代对象变为迭代器
li = Foo('zz', 18)
for i in li:
print(i) # 循环取值
# 对象.__iter__() 的返回值为迭代器
li.__iter__() # <list_iterator object at 0x0000025A44753148>