扩大
缩小
人生本来就短暂,为什么还要栽培苦涩。
返回顶部

迭代器,三元表达式,列表推存式,字典生成式,生成器生成式,生成器,递归

1. 迭代器

迭代器:他不是函数,只是一个称呼。

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

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

除了数字类型,所有数据类型都是可迭代对象。可迭代的对象:Python内置str、list、tuple、dict、set、file都是可迭代对象。

特点:

  1. 内置有__iter__方法的都叫可迭代的对象。
x = 10 #则不是可迭代对象

可迭代对象位  .__iter__
s = "adc"
s.__iter__()
lt = [1,2,3]
lt.__iter__()
tup = (1,)
tup.__iter__()
se = {1}
se.__iter__()
dic ={"a":1}
dic.__iter__()

fw = open("text","a+",encoding="utf-8")
fw.seek(0,0)
fw.__iter__()
# 除了数字类型,所有数据类型都是可迭代对象

迭代器对象

迭代器对象:含有 .__ iter __ 和 .__ next __方法的对象就是迭代器对象。

概念:可迭代的对象执行__iter__方法得到的返回值。并且可迭代对象会有一个__next__方法。

只有字符串和列表都是依赖索引取值的,而其他的可迭代对象都是无法依赖索引取值的。因此我们得找到一个方法能让其他的可迭代对象不依赖索引取值。

s = "adc"
s_iter = s.__iter__()
print(s_iter.__iter__()) #不依赖索引取值
print(s[0]) #索引取值
print(s_iter.__iter__())
print(s[1])
print(s_iter.__iter__())
print(s[2])
为什么要有迭代器对象:提供了 不依赖索引取值的手段
dic = {'a': 1, 'b': 2, 'c': 3}
dic_iter = dic.__iter__()
print(dic_iter.__next__())  # 迭代取值 --》 基于上一个值
print(dic_iter.__next__())
print(dic_iter.__next__())  #取不到则报错

为什么要有迭代器对象:提供了 不依赖索引取值的 手段

dic = {'a': 1, 'b': 2, 'c': 3}
dic_iter = dic.__iter__()
print(dic_iter.__next__())  #a
print(dic_iter.__next__()) #b
print(dic_iter.__next__())  #c
print(dic_iter.__next__())  #取不到则报错

对上面迭代问题,我们使用while循环精简 使用try: escept stopiteration:的异常处理模块

模板
dic_iter = dic.__iter__()
 while True:
    try:
         print(dic_iter.__next__())
    except StopIteration:
         break
列题:
s = 'hello'
iter_s = s.__iter__()

while True:
    try:
        print(iter_s.__next__())
    except StopIteration:        #除了迭代对象(hello)停止迭代运行 h e l l o
        break

总结

迭代器对象:执行可迭代对象的__iter__方法,拿到的返回值就是迭代器对象。

特点:

  1. 内置__next__方法,执行该方法会拿到迭代器对象中的一个值
  2. 内置有__iter__方法,执行该方法会拿到迭代器本身
  3. 文件本身就是迭代器对象。

缺点:

  1. 取值麻烦,只能一个一个取,并且只能往后取,值取了就没了
  2. 无法使用len()方法获取长度

for循环原理

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

for循环称为迭代器循环,in后必须是可迭代的对象

list = [1,2,3,4]
for i in liast:
    print(i)  # 1,2,3,4

牢记:

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

迭代器对象: 含有__ iter __ 和 __ next __ 方法叫做迭代器对象 --> 只有文件时迭代器对象 --> 迭代器使用 __ iter __依然是迭代 器

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

2.三元表达式

条件成立时的返回值 if 条件 else 条件不成立时的返回值

通常用:
x = 10
y = 20
if x > y:
    print(x)
else:
    print(y)  #20
    
三元表达式:
x = 10
y = 20
print(f"x if x > y else y: {x if x > y else y}")  #x if x > y else y: 20

3.列表推存式

lt = []
for i in range(10):
    lt.append(i)
lt = [i**2 for i in range(10)]
print(lt)  #[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

from typing import Iterable #导出一个可迭代对象类型。

print(isinstance(range(10),Iterable)) #判断是否属于该数据类型。

4.字典生成式

dic = {}
for i in range(10):
	dic[i] = i
print(dic) # 0:0 1:1...9:9

dic = {i:i**2 for i in range(10)}
print(dic) # 0:0 1:1 2:4.....9:81

zip (解压缩)

res = zip([1,2,3],[4,5,3,2,2],"qwer")  ## res是一个迭代器,__next__返回元组
print(res.__next__())  #(1, 4, 'q')
print(res.__next__())  #(2, 5, 'w')
print(res.__next__())  #(3, 3, 'e')
print(res.__next__())  #报错 #则列表中的数取完,则报错。
lt1 = ["a","b","c"]
lt2 = [1,2,3]
dic = {k:v**2 for k,v in zip(lt1,lt2)}
print(dic)  #{'a': 1, 'b': 4, 'c': 9}

lt = list("abc")
print(lt)  # ['a','b',"c"]

5.生成器生成式

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

# 生成器表达式:  看成老母鸡,节省内存空间,用就下蛋
g = (i for i in range(10000))
print(g)
for i in g:
    print(i)
    
 # 列表推导式: 看成一筐鸡蛋,非常占用内存空间   
lt = [i for i in range(10000)]
print(lt)

6.生成器

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

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

def ge():    #1 #3  #6
    yield 3         #7 #9
    yield 4            #10
print(ge())  #2  ge()得到一个生成器 --> 生成器本质是迭代器  <str_iterator object at 0x00000293FE9BE148>   列print(s_iter.__iter__())。。。
g=ge()       #4   得到一个生成器
print(g.__next__()) #5  
print(g.__next__()) #8  print--> 3,4

#for i in g:
 #   print(i)  #简化上面两个打印值

6.1 特征

# yield的特性
# 1. 暂停函数
# 2. 通过next取值

# return的特性
# 1. 终止函数
# 2. 通过调用函数拿到值

迭代器套迭代器

ef sub_generator():
    yield 1
    yield 2
    for i in range(3):
        yield i
for i in sub_generator():
    print(i)   # 1  2 0 1 2
def range(start)
	count = 0 
    while count <start:
        yield count 
        count += 1
for i in range(10)
print(i)

7.递归

递归:表示回归。

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

import sys
sys.setrecursionlimit(10)
print(sys.getrecursionlimit())  #10

def a():
    x = 1
    print(x)
    a()     #函数a内部直接调用函数a本身
a()

#每一次递归,会不会结束函数?不会,并且每一次递归都会开辟内存空间,如果一直开辟内存就炸掉了,所以最多递归1000次

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

count = 0
def a():
    global count
    count +=1
    print(count)
    if count == 5:
        return
    a()              
a()        #1,2,3,4,5

递归的特点

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

2.必须要有推出条件

3.递归必需要有规律。

列题:

玉阳 20岁 ; 后面的同学大2岁,后面的后面的同学比后面的同学大2岁; 求第6位同学的年龄

'''  #规律
20
20 + 2
20 + 2 + 2
20 + 2 + 2
'''

def age(x):
    if x == 0:
        return 18
    x -= 1
    return age(x) + 2


res = age(6)
print(res)  # 32

'''
res = 30 
res = 28 + 2
res = 26 + 2 + 2
res = 24 + 2 + 2 + 2
res = 22 + 2 + 2 + 2 + 2
res = 20 + 2 + 2 + 2 + 2 + 2
res = 18 + 2 + 2 + 2 + 2 + 2 + 2
posted @ 2019-09-24 19:29  晴天sky  阅读(137)  评论(0编辑  收藏  举报
左边日期 搜索的制定样式