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 總結

    遞歸:

    • 函數內部調用函數本身
    • 必需要有退出條件
    • 遞歸必需要有規律
相關文章
相關標籤/搜索