函数、参数类型及生成器 迭代器对象

函数

  • 常用的功能块编写成函数,放在函数库中供公共使用,内置函数可以直接调用。
  • 提高编程效率以及代码重用性,具有特定功能。是结构化设计程序的基础,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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值