1. 程式人生 > 其它 >leetcode2097 合法重新排列數對

leetcode2097 合法重新排列數對

迭代器

常見內建函式(二)

# help()  檢視註釋資訊
# help(len)  檢視len函式的註釋資訊

# id()  返回相當於目標記憶體地址的一串數字
# print(id('name'))
# >>>18096640  相當於name字串的記憶體地址

# int()  型別轉換,進位制轉換,其他型別轉成整形,其他進位制轉換成十進位制
# res = '123'
# b = 0b101010
# print(int(res),type(res))  字串必須是純數字,否則報錯
# print(int(b))
# >>>123 <class 'str'>
# >>>42

# isinstance() 判斷資料型別
# print(isinstance(12,str))
# print(isinstance(12,int))
# >>>False  # 結果不是預期型別返回FALSE
# >>>True  # 結果是預期型別返回True

# pow()  冪指數
# print(pow(2,3))  # 第一個引數為底數,第二個引數為指數
# >>>8

# round() 四捨五入
# print(round(11.6778,2))  # 第二個引數可以指定保留幾位小數,不寫預設一位小數
# print(round(11.5))
# >>>11.68
# >>>12

# sum() 求和
# print(sum([1,2,3,4,5,6,7,8,9]))
# >>>45

可迭代物件

# 1. 什麼叫迭代?
	迭代就是更新換代,每一次迭代的過程都要依賴於上一次的結果
'''
	n = 1
	while True:
		print(n)
	# 上述只是單純的迴圈,沒有結果的變化,不屬於迭代
	while True:
		n += 1
		print(n)
	# 上述程式碼就屬於迭代,因為結果每次都是根據上一次的在變化
	l1 = [11, 22, 33, 44, 55]
    # 迭代取值
    i = 0
    while i < len(l1):
        print(l1[i])
        i += 1
'''

# 2. 什麼是可迭代物件?
	可以點出__iter__方法的都可以稱為可迭代物件
    '''__iter__讀作雙下iter'''

# 3. 哪些資料型別是可迭代物件?
i = 11  # 整型不是
f = 11.11  # 浮點型不是
s = 'jason'  # 字元是
l = [1,2,3,4]  # 列表是
d = {'name':'jason','age':18}  # 字典是
t = (1,2,3,4)  # 元組是
se = {1,2,3,4,5}  # 集合是
b = True  # 布林值不是
f = open()  # 檔案是
def index():pass  # 普通函式不是
'''
屬於可迭代物件的有
    字串、列表、字典、元組、集合、檔案物件
可迭代物件其實就是為了後續迭代取值做準備
    提供了不依賴於索引取值的方式
可迭代物件都可以進行for迴圈!
'''

迭代器物件

# 1. 什麼是迭代器物件?
	可迭代物件呼叫__iter__方法後生成的就是迭代器物件
# 2. 迭代器物件有什麼特徵?
	可以點出__iter__和__next__方法
# 3. 如何理解迭代器物件
	迭代器物件能夠極大的節省儲存空間,類似於工廠,只有你需要使用資料的時候他才給你資料,不需要使用他就是一個工廠殼子,只佔工廠面積的空間
# 4. 迭代器物件如何取值?
	呼叫__next__方法即可,呼叫一次給你一個值,取完了再取會直接報錯!!!
     ps:開闢了一種不需要索引取值的方式(for迴圈底層依據的就是迭代器物件)
  '''有了迭代器物件才出現了針對字典和集合的迭代取值操作'''
# 5. 迭代器物件補充說明
	# 1. 雙下方法簡寫(不是所有雙下方法都可以)
    '''
    	__方法名__  等價於  方法名()
    	__iter__  iter()
    	__next__  next()
    '''
    eg:
        print(len([1,2,3,4,5,6]))
        print([1,2,3,4,5,6].__len__())
    執行結果:
        6
        6
    # 2. 有些可迭代物件本身也是迭代器物件>>>:檔案物件
    # 3. 可迭代物件呼叫一次__iter__方法變成迭代器物件,繼續呼叫結果還是迭代器物件,所以,檔案本身既是可迭代物件又是迭代器物件,因為無論執行多少次__iter__,檔案物件都還是迭代器物件
    eg:
        res = 'petter'
        res1 = 'oscar'
        print(res.__iter__())
        print(res1.__iter__().__iter__().__iter__())
    執行結果:
        <str_iterator object at 0x020D8B30>
		<str_iterator object at 0x020D8BF0>
    # 無論執行多少次__iter__,結果都是iterator物件
    # 4. 迭代取值的要求
    '''迭代器物件每執行一次__next__,去除一個值'''
    eg:
        res = 'petter'
        print(res.__iter__().__next__())  
        print(res.__iter__().__next__())
        print(res.__iter__().__next__())
        s = res.__iter__()
        print(s.__iter__().__next__())
        print(s.__iter__().__next__())
        print(s.__iter__().__next__())
    執行結果:
        p
        p
        p
        p
        e
        t
    # 為什麼前三次取值結果都是p,而後面三次是p e t?
    '''
    前三次取值,每次取值之前都把res執行了一遍__iter__,相當於每次取值前都把res初始化成一個新的迭代器物件,所以只能取出p,而後面s是res轉換成的迭代器物件,迭代器物件再呼叫__iter__,結果還是他本身,哪怕你已經取過值了,結果還是本身,再取值也是接著後面取
    '''

for迴圈的內部原理

# for迴圈內部就是一個迭代器
# 用迭代器輸出列表
eg:
    l1 = [1,2,3,4,5,6,7,8,9]
    res = l1.__iter__()
    i = 0
    while i < len(l1):
        print(res.__next__())
        i += 1
執行結果:
    1
    2
    3
    4
    5
    6
    7
    8
    9
# 通過結果可以看到,這段程式碼實現的功能和for迴圈陣列l1的結果一毛一樣,所以可以看出,for迴圈的本質就是通過迭代器挨個取值。這也是為什麼可迭代物件都可以進行for迴圈
"""
for迴圈底層原理
    for 變數名 in 可迭代物件:
        迴圈體程式碼
1.會將in後面的資料呼叫__iter__()變成迭代器物件
    為什麼檔案物件也可以for迴圈 因為本身就是迭代器物件 再次呼叫不變
2.針對產生的迭代器物件依次呼叫__next__()方法迭代取值
3.當值取完之後 會自動處理報錯並退出迴圈
"""

異常處理

# 1. 什麼是異常?
	程式碼執行出錯之後就是異常 異常會導致程式立刻停止 
  是我們以後在程式設計過程中需要極力避免的情況(異常的外號>>>:bug)

# 2. 異常資訊的組成部分
	Traceback (most recent call last):
     File "/Users/jiboyuan/PycharmProjects/day16/05 異常處理.py", line 3, in <module>
        name
    NameError: name 'name' is not defined
    1.line關鍵字所在的一行
        用於提示你程式碼哪一行出錯了 點選地址可以直接跳到出錯的那一行
        '''如果報錯的資訊很長 一般最後一個才是'''
    2.NameError錯誤的型別
        程式碼的報錯也可以分為很多型別,錯誤型別會以Error結尾
    3.name 'name' is not defined
        具體的報錯原因(就是解決報錯的答案),可以把這一行放到百度搜,有奇效,具體報錯內容跟在錯誤型別後面,還是找Error就可以了

# 3. 異常的分類
	1. 語法異常
    不被允許的,如果出錯了必須立刻改正,程式碼執行不起來,必須改正後才可以跑起來
    2. 邏輯異常
    可以允許,如果出錯了儘快修改,程式碼可以執行,但是得不到想要的結果
    
# 4. 異常的型別
	# 異常的型別有很多,可以根據名字判斷異常種類,如
    NameError  名稱錯誤
    IndexError  索引錯誤
    KeyError    鍵錯誤
    # 異常型別都是由種類+Error組成,找到這個單詞,照著名字翻譯就可以
    

異常處理實操

'''有時候針對可能會出錯的程式碼 也可以自己提前寫好處理措施'''
	正常情況下程式碼出錯 肯定是直接導致程式停止
  但是也可以自己通過程式碼來處理 從而避免程式的停止
# 基本語法結構
	try:
        可能出錯的程式碼
    except 錯誤型別1 as e:  # e指代錯誤資訊,此處語法類似於open
        處理措施
    except 錯誤型別2 as e:
        處理措施
    ...

# 萬能異常處理
	try:
        可能出錯的程式碼
    except Exception as e:  # 當我們不知道會出什麼型別的錯時,就用這個也可以
        處理措施
       
##############################################
異常處理使用準則
	1.被檢測的程式碼越少越好
  	2.能儘量少用就儘量少用
##############################################

異常處理了解

# 1. 和else連用
	作用:當try監測的程式碼沒有發生異常,正常執行過後執行else子程式碼
	語法:
        try:
            可能出錯的程式碼
        except Exception as e:
            處理措施
        else:
            沒有出錯執行的程式碼
    
# 2. 和finally連用
	作用:無論try監測的程式碼有沒有發生異常,執行完程式碼後都會執行finally子程式碼
    語法:
        try:
            可能出錯的程式碼
        except Exception as e:
            處理措施
        finally:
            異常處理後執行的程式碼
            
# 3. 全部整合到一起使用
  try:
      name
  except Exception as e:
      print(e)
  else:
      print('沒報錯 好極了')
  finally:
      print('管你錯不錯 都執行')
        
# 4.斷言(瞭解中的瞭解)
	作用:針對一個可能成立的結論進行預測,成功則沒啥事,失敗報錯!!!
   	語法: assert 被斷言內容
	num = 1
	assert isinstance(num,int)  # num是int型別,程式正常執行
    assert 1 > 2  # 1 < 2,程式報錯

# 5.主動報錯(需要掌握)
	raise NameError('不爽 就要作!!!')
  '''由於是主動報錯 所以可以非常明確的知道錯誤的型別'''

用異常處理和迭代器實現自定義for迴圈

# 上面我們寫了自定義for迴圈,當時我們自己定義了while迴圈結束條件,其實還可以用異常處理結束迴圈
eg:
    l1 = [1,2,3,4,5,6,7,8,9]
    # 迭代取值
    res = l1.__iter__()
    try:
        while True:
            print(res.__next__())
    except Exception as e:
        print(e)
執行結果:
        1
        2
        3
        4
        5
        6
        7
        8
        9
# 這樣寫省去了計數的部分,更節省空間
# for迴圈本質:
	進行了異常處理的迭代器

迭代取值與索引取值的對比

1. 索引取值
	優勢:可以重複取值,取值沒有固定方向
   	劣勢:只能致辭有序的容器型別,無序的無法取值相容新沒有迭代取值高,且需要一個儲存索引的記憶體空間,需要的空間資源更大
2. 迭代取值
	優勢:相容所有的容器型別,不需要額外空間儲存索引
     劣勢:只能從左往右取值,並且無法重複取值
  # 真正底層的迭代取值後續可能很少用 一般都是for迴圈代替
"""
迭代器裡面的東西是固定的 沒取一個就會少一個 取完就空了
"""