python基础--迭代器、生成器、递归

迭代器

迭代器:不是函数,只是一个称呼而已

python中一切皆对象(数据类型)

可迭代对象:含有.__iter__方法的数据类型就叫做可迭代对象

name = 'allen'.__iter__()
lis = [1,2,3,4]
iter_lis = lis.__iter__()
dic = {'a':1,'b':2,'c':3}
iter_dic = dic.__iter__()

除了数字类型,所有数据类型都是可迭代对象

迭代器对象: 含有__iter__和__next__方法的对象就是迭代器对象

name = 'allen'.__iter__()
print(name.__next__())

lis = [1,2,3,4]
iter_lis = lis.__iter__()
print(iter_lis.__next__())

dic = {'a':1,'b':2,'c':3}
iter_dic = dic.__iter__()
print(iter_dic.__next__())

迭代器对象的作用:提供了 不依赖索引取值的 手段

for循环原理(for循环本质就是一个while循环,只不过是一个一定可控的while循环)

dic = {'a': 1, 'b': 2, 'c': 3}
print(dic_iter.__next__())  # 打印结果为:a
print(dic_iter.__next__())	# 打印结果为:b
print(dic_iter.__next__())	# 打印结果为:c
print(dic_iter.__next__())	# 执行到此行报错

可迭代对象: 含有__iter__方法叫做可迭代对象 --> 除了数字类型都是可迭代对象 --> 可迭代对象使用__iter__变成迭代器

迭代器对象: 含有__iter__和__next__方法叫做迭代器对象 --> 只有文件是迭代器对象 --> 迭代器使用__iter__依然是迭代器

可迭代对象不一定是迭代器对象; 迭代器对象一定是可迭代对象

三元表达式

x = 10
y = 20
if x > y:
	print(x)
else:
	print(y)

三元表达式 --> 三目表达式

print(x) if x > y else print(y)  #  --> 仅作了解

条件成立走这里 if 条件 else 条件不成立走这里

列表推导式

要生成一个1到100的列表,可以用for循环

lt = []
for i in range(100):
    lt.append(i)

上述方法繁琐,用列表推导式可以轻松实现

lt = [i for i in range(100)]

"for i in range(100)"是固定的结构,前边的i可以做其他运算,如下:

lt = [i**2 for i in range(10)]

要判断数据是什么类型,可用以下方法:

from typing import Iterable # 导出一个可迭代对象类型
print(isinstance(range(10),Iterable)) # 判断是否属于该数据类型

字典生成式

字典生成器:用于生成字典

要生成字典,我们可以用基本知识完成,过程如下:

dic = {}
for i in range(10):
	dic[i] = i
	print(dic)

也可以用类似与列表推导式的方法:

dic = {i:i**2 for i in range(10)}
print(dic)

重点:用zip方法将两个列表生成字典

lt1 = ['a', 'b', 'c']
lt2 = [1, 2, 3]
dic = {k: v ** 2 for k, v in zip(lt1, lt2)}
print(dic)

generator 生成器

generator 生成器: 本质就是迭代器,生成器就是一个自定义的迭代器

生成器:含有yield关键字的函数叫做生成器

def ge():
    yield 3  # 一个yield相当于一个next; 暂停函数
    yield 4
print(ge())  # ge()得到一个生成器 --> 生成器本质是迭代器
g = ge()  # 得到一个生成器
print(g.__next__())
print(g.__next__())

yield的特性:

  1. 暂停函数

  2. 通过next取值

return的特性

  1. 终止函数

  2. 通过调用函数拿到值

生成器表达式

列表推导式:egg_list = ['鸡蛋%s' %i for i in range(10)],直接生成装满元素的列表。形象地称为一筐鸡蛋

生成器表达式:laomuji = ('鸡蛋%s' %i for i in range(10)), 这只是表达式,不取就不生成元素,取一次生出一个。形象的称为会下蛋的老母鸡

laomuji = ('鸡蛋%s' %i for i in range(10))	# 定义一个生成器
print(laomuji)
print(next(laomuji))	# 打印第一个值。next 等效于.__next__
print(laomuji.__next__())	# 打印第二个值
print(next(laomuji))	# 打印第三个值

一个一个取值就用print(next(laomuji))

一次取所有值就用print(list(laomuji))

生成器的优点:

1、延迟计算

一次返回一个结果。也就是说,它不会一次性生成所有的结果,这对于大数据量的处理会非常省时省空间。

2、代码简洁,提高可读性

练习题一

def demo():
    for i in range(4):
        yield i

g=demo()

g1=(i for i in g)
g2=(i for i in g1)

print(list(g1))
print(list(g2))

练习题二

def add(n,i):
    return n+i

def test():
    for i in range(4):
        yield i

g=test()
for n in [1,10]:
    g=(add(n,i) for i in g)

print(list(g))

递归函数

顾名思义传递并回归

递归: 函数a内部直接调用函数a本身

递归函数定义形式:

def a():	# 定义一个函数a
	x = 1
	print(x)
	a()	# 函数a内部调用自己
a()	# 调用函数a

每一次递归,不会结束函数,并且每一次递归都会开辟内存空间,如果一直开辟内存就炸掉了,所以最多递归997次,python提供了修改递归次数的方法:

import sys
sys.setrecursionlimit(10000)	# 把递归次数改为10000次
print(sys.getrecursionlimit())

真正的递归必须得要有 退出条件

count = 0
def a():
    global count
    count += 1
    print(count)
    if count == 5:
        return
    a()
a()

递归函数的要素:

  1. 函数内部调用函数自己

  2. 必须要有退出条件

  3. 递归必须要有规律

练习题:

1、小明20岁 ; 后面的同学大2岁,后面的后面的同学比后面的同学大2岁; 求第6位同学的年龄

def age(x):
    if x == 0:
        return 20
    x -= 1
    return age(x) + 2
res = age(3)
print(res)

2、小明买了一包瓜子,每天吃当天瓜子数量的一半,吃到第8天发现还剩5颗,用递归求他一共买了多少颗瓜子

def sum(x):
    if x == 0:
        return 5
    x -= 1
    return sum(x) * 2
res = sum(8)
print(res)
posted @ 2019-09-24 21:27  AllenCH  阅读(287)  评论(0编辑  收藏  举报