num = float(input('請輸入一個數字:')) result = '偶數' if num%2 == 0 else '奇數' print(result) '''相似於''' if num%2 == 0: print('偶數') else: print('奇數')
推導式是python提供的另外一種建立數據類型的方式,有列表推導式、集合推導式、字典推導式,沒有元祖推導式。python
x = [1,2,3,4,5] y = [6,7,8,9,10] transfrom = [1 if i%2==0 else 0 for i in x if i > 2] print(transfrom) '''相似於''' transfroms = [] for i in x: if i > 2: if i%2==0: transfroms.append(1) else: transfroms.append(0) print(transfroms) result = [i+e for i in x if i%2==0 for e in y if e%2 == 0] print(result) print(type(result)) '''相似於''' results = [] for i in x: for e in y: if i%2==0: if e%2==0: results.append(i + e) print(results) '''1,2,3,4組成無重複三位數''' a = [str(i) for i in range(1,5)] f = [b+c+d for b in a for c in a for d in a if b != c != d != b] print(f)
'''1,2,3,4組成無重複三位數''' a = [str(i) for i in range(1,5)] f = {b+c+d for b in a for c in a for d in a if b != c != d != b} #把[]改成{}便可。 print(len(f))
x = [1,2,3,4,5] y = [6,7,8,9,10] result = {i:e for i,e in zip(x,y)} #zip函數返回zip對象,被遍歷時返回一個序列下標相同的元素組成的元祖 res = {i:e for i,e in enumerate(y)} #enumerate()函數返回enumerate對象,被遍歷時返回一個元祖(下標,元素)。 print(result) print(type(result)) '''相似於''' results = {} for i,e in enumerate(y): results[i] = e print(results) print(zip(x,y).__next__())
在Python中,列表,字典等序列的全部數據都在內存裏,若是有海量數據,而咱們僅僅須要訪問幾個元素的時候,那絕大多數元素佔用的空間都白白浪費了。那麼,有沒有既想要獲得龐大的數據,又想讓它佔用空間少的方法呢?,那就用生成器!按照某種算法不斷推算出後續的元素,須要訪問某個元素的時候,只需推算出,而不是從龐大的數據序列裏取出算法
。這樣一邊循環一邊計算的機制,稱爲生成器:generator。若要訪問generate對象的元素,須要調用它的__next__()函數,或把generate對象傳入next()函數,一個__next__()函數只拿出一個,以後循環中止在當前位置,下一個再取值再從中止位置繼續向前取值。若推算完全部元素,還調用__next__(),則會拋出StopIteration異常,next()函數也同樣。app
'''方式一(生成器表達式):只要把一個列表推導式式的[]改爲(),就建立了一個generator對象。''' generate = (e for e in range(1,100,2)) print(type(generate)) #訪問元素 print(generate.__next__()) print(generate.__next__()) print(next(generate)) #在同一個對象裏,不管調用next()或__next__()函數,它們都是接力推算的。 print(generate.__next__()) print(next(generate)) print("*"*10,end='\n'*2) generate2 = (e for e in range(1,10,2)) #從新建立新對象 for e in generate2: #for循環會不斷調用__next__函數推算出後續元素,並返回它,直到捕獲StopIteration異常,而後自動結束for循環。 print(e) '''方式二:若是一個函數中包含yield關鍵字,那麼這個函數就再也不是一個普通函數,而是一個generator。 調用函數就是建立了一個生成器(generator)對象。yield至關於 return 返回一個值,而且記住這個返回的位置, 下次迭代時,代碼從yield的下一條語句開始執行。''' def test(seq): index = 0 while index < len(seq): yield seq[index] #遇到yield時,返回一個值,執行中止,並記住該位置,下次調用__next__()時,代碼從yield的下一條語句開始執行。。 print('*'*10) print('上一個元素的下標是{}'.format(index)) index += 1 str1 = 'abcdefgh' generate3 = test(str1) print(type(generate3)) print(generate3.__next__()) print(generate3.__next__()) #.send() 和next()同樣,都能讓生成器繼續往下走一步(下次遇到yield停),但send()能傳一個值,這個值做爲yield表達式總體的結果. def test1(): count = 1 while count < 9: it = yield count print('*'*10) count += 1 if it: print('你第{}次使用的是:send()函數傳值,並賦值給了變量step,step = {}'.format(count,it)) else: print('你第{}次使用的是:__next__()函數,未給變量step傳值,默認值爲None,step = None'.format(count)) generate4 = test1() print('返回值爲:{}'.format(generate4.send(None))) #不能使用send()函數向剛啓動的生成器發送非空值,否則使用__next__(),不然報錯。 print('返回值爲:{}'.format(generate4.send(6))) print('返回值爲:{}'.format(generate4.send(8))) print('返回值爲:{}'.format(generate4.__next__())) print('返回值爲:{}'.format(generate4.send(9))) print('返回值爲:{}'.format(generate4.__next__()))
def permutations(iterable, r=None): # permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC # permutations(range(3)) --> 012 021 102 120 201 210 pool = tuple(iterable) n = len(pool) r = n if r is None else r if r > n: return indices = list(range(n)) cycles = list(range(n, n-r, -1)) yield tuple(pool[i] for i in indices[:r]) while n: for i in reversed(range(r)): cycles[i] -= 1 if cycles[i] == 0: indices[i:] = indices[i+1:] + indices[i:i+1] cycles[i] = n - i else: j = cycles[i] indices[i], indices[-j] = indices[-j], indices[i] yield tuple(pool[i] for i in indices[:r]) break else: return
Iterable(可迭代對象)
: 有迭代能力的對象,一個類,實現了__iter__()
,那麼就認爲它有迭代能力,一般此函數返回一個實現了__next__()
的對象(雖然這個要求不強制),若是本身實現了,你能夠返回self
,固然這個返回值不是必須的。ide
Iterator(迭代器)
: 迭代器(固然也是Iterable
),同時實現了__iter__()
和__next__()
的對象,缺乏任何一個都不算是Iterator,其中
函數__next__()
應該在迭代完成後,拋出一個StopIteration
異常。
可使用 collections.abc 裏面的 Iterator
和 Iterable
配合 isinstance
函數來判斷一個對象是不是可迭代的,是不是迭代器對象。spa
咱們在使用for
語句的時候,python內部實際上是把for
後面的對象上使用了內建函數iter()
,返回一個迭代器對象(Iterator)
,它主要映射到了類裏面的__iter__()
函數,此函數返回的是一個實現了__next__
的對象。for
語句會自動處理這個StopIteration
異常以便結束for
循環。code
from collections.abc import * list1 = [1,2,3,4,5] str1 = 'abcdef' list2iterator = iter(list1) #接受可迭代對象,返回迭代器對象。 str2iterator = iter(str1) '''isinstance() 函數來判斷一個對象是不是一個已知的類型,相似 type()。type() 不會認爲子類是一種父類類型,不考慮繼承關係。 isinstance() 會認爲子類是一種父類類型,考慮繼承關係。''' print('list1是可迭代對象嗎?:{} | list1是迭代器對象嗎?:{}'.format(isinstance(list1,Iterable),isinstance(list1,Iterator))) print('str1是可迭代對象嗎?:{} | str1是迭代器對象嗎?:{}'.format(isinstance(str1,Iterable),isinstance(str1,Iterator))) print('list2iterator是可迭代對象嗎?:{} | list2iterator是迭代器對象嗎?:{}'.format(isinstance(list2iterator,Iterable),isinstance(list2iterator,Iterator))) print('str2iterator是可迭代對象嗎?:{} | str2iterator是迭代器對象嗎?:{}'.format(isinstance(str2iterator,Iterable),isinstance(str2iterator,Iterator))) class B(object): def __next__(self): raise StopIteration class A(object): def __iter__(self): return B() a = A() b = B() print(isinstance(a, Iterable)) print(isinstance(a, Iterator)) print(isinstance(b, Iterable)) print(isinstance(b, Iterator)) '''製做本身的迭代器''' class MyIterator(): def __init__(self,seq): self.index = 0 self.seq = seq def __iter__(self): return self def __next__(self): if isinstance(self.seq,dict): self.seq = list(self.seq.values()) res = self.seq[self.index] self.index += 1 return res else: if self.index < len(self.seq): element = self.seq[self.index] self.index += 1 return element else: raise StopIteration() #在不想繼續有迭代的狀況下拋出一個StopIteration的異常,由for語句會捕獲這個異常,而且自動結束for。 test = 'abcdef' testIter = MyIterator(test) print(isinstance(testIter,Iterable)) print(isinstance(MyIterator,Iterable)) #__iter__()和__next__()是類的普通方法,不是類方法或靜態方法,只能被實例化對象調用,因此不能經過類名判斷它是不是迭代器。 print(isinstance(MyIterator(test),Iterator))