day-13

1. 迭代器

python中一切皆对象app

迭代器和装饰器不一样,迭代器只是一个称呼而已。函数

1.1 可迭代对象

含有 .__iter__ 方法的数据类型叫作可迭代对象,除了数字类型,全部数据类型都是可迭代对象。code

x = 10  # 不是可迭代对象

s = 'abc'
s.__iter__()

lt = [1, 2, 3]
lt.__iter__()

tup = (1,)
tup.__iter__()

dic = {'a': 1}
dic.__iter__()

se = {1}
se.__iter__()

fw = open('test.txt', 'a+', encoding='utf8')
fw.seek(0, 0)
fw.__iter__()

1.2 迭代器对象

含有 .__iter__.__next__ 方法的对象就是迭代器对象,只有文件是迭代器对象对象

dic = {'a': 1, 'b': 2, 'c': 3}
dic_iter = dic.__iter__()   # 2.其余类型都须要这样间接使用
print(dic_iter.__next__())
print(dic_iter.__next__())
print(dic_iter.__next__())

fw = open('test.txt', 'a+', encoding='utf8')
fw.seek(0, 0)
fw.__iter__()
fw.__next__()   # 1.文件类型能够直接使用 .__next__() 方法
print(fw.__next__())
print(fw.__next__())
print(fw.__next__())

运行结果:递归

a
b
c
------------------------------
1

2

3


Process finished with exit code 0

1.2.1 迭代器对象的做用

提供了一种不依赖索引取值的手段。索引

1.2.2 for 循环的原理

# for循环原理(for循环本质就是一个while循环,只不过是一个必定可控的while循环)
dic = {'a': 1, 'b': 2, 'c': 3}  # 要求逐个取出字典的 key

dic_iter = dic.__iter__()
while True:
    try:
        print(dic_iter.__next__())
    except StopIteration:
        break
        
# print('-'*30)

for i in dic:  # for循环 --> 迭代循环
    print(i)
    
# 标准版
# def for(iterable):
#     iterator = iterable.__iter__()
#     while True:
#         try:
#             print(iterator.__next__())
#         except StopIteration:
#             break
a
b
c
------------------------------
a
b
c

Process finished with exit code 0

1.3 总结

  • 可迭代对象:
    • 含有 .__iter__ 方法叫作可迭代对象
    • 除了数字类型都是可迭代对象
    • 可迭代对象使用 .__iter__ 变成迭代器
    • 可迭代对象不必定是迭代器对象
  • 迭代器对象:
    • 含有 .__iter__.__next__ 方法叫作迭代器对象
    • 只有文件是迭代器对象
    • 迭代器使用 .__iter__ 依然是迭代器
    • 迭代器对象必定是可迭代对象

2. 三元表达式

格式:条件成立时的返回值 if 条件 else 条件不成立时的返回值ip

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

使用三元表达式:内存

print(x) if x > y else print(y)

3. 列表推导式

建立一个列表generator

lt = []

for i in range(10):
    lt.append(i)

使用列表推导式:

lt = [i for i in range(10)] 
lt = [i ** 2 for i in range(10)]    # in 后面加可迭代类型

4. 字典生成式

4.1 字典生成式

生成一个列表:

dic = {}

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

使用字典生成式:

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

4.2 zip()方法

lt1 = ['a', 'b', 'c']
lt2 = [1, 2, 3]

dic = {k: v for k, v in zip(lt1, lt2)}
print(dic)

zip() 方法的说明:

res = zip([1, 2, 3], [4, 2, 3, 4, 2, 3, 4, 2, 3],
          'abcadsfasdfasdf')  # res是一个迭代器,__next__返回元组
print(res.__next__())  # type:tuple
print(res.__next__())  # type:tuple
print(res.__next__())  # type:tuple

打印结果:

(1, 4, 'a')
(2, 2, 'b')
(3, 3, 'c')

Process finished with exit code 0

5. 生成器

生成器:本质上是迭代器,它提供了一种方便的自定义迭代器的途径。

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

5.1 生成器和函数的区别

def func():
    print(1)


def ge():
    yield 1


print(func)
print(ge)   
print('-' * 30)
print(func())
print(ge())

运行结果:

<function func at 0x00000221B4673798>   # 打印出了函数 func 的内存地址
<function ge at 0x00000221B4673828> # 打印出了函数 ge 的内存地址
------------------------------
1
None    # func() 调用了函数,并获得了默认的返回值 None
<generator object ge at 0x00000221B4674048> # ge() 返回了生成器对象的地址,并无执行里面的代码

Process finished with exit code 0

5.2 生成器的特性

  • 生成器的本质是迭代器
def ge():
    yield 1 # 一个yield至关于一个next; 暂停函数
    yield 2
    yield 3

    
g = ge()    # 获得一个生成器
print(g.__next__())
print(g.__next__())
print(g.__next__())

运行结果:

1
2
3

Process finished with exit code 0
  • yield 的特性
    • 暂停函数
    • 经过 .__next__() 取值

5.3 练习-简单的 range 方法

def range(start):
    count = 0
    while count < start:
        yield (count)
        count += 1


g = range(3)
print(g.__next__())
print(g.__next__())
print(g.__next__())

6. 生成器表达式

生成一个生成器:

# 生成器表达式
g = (i for i in range(5))

生成器表达式和列表推导式

# 生成器表达式
g = (i for i in range(5))   # 节省内存空间,须要用的时候取出来
# 列表推导式
lt = [i for i in range(5)]  # 一次性生成数据,占用内存空间

7. 递归

  • 递归:函数内部直接或间接的又调用了函数自己

    # 这种形式叫作递归
    def a():
        x = 1
        print(x)
        a()
    a()

    因为每一次的递归,都没有结束函数的条件,而且每一次递归,都会开辟新的内存空间存放变量值,一直这样的话内存会爆掉,因此 python 给了限制最多递归1000次。

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

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

    运行结果:

    1
    2
    3
    4
    5
    
    Process finished with exit code 0

    7.1 总结

    递归:

    • 函数内部调用函数本身
    • 必需要有退出条件
    • 递归必需要有规律
相关文章
相关标签/搜索