乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Python 實(shí)用編程技巧(迭代篇)

       dinghj 2019-04-17

      1.如何實(shí)現(xiàn)可迭代對(duì)象和迭代器對(duì)象

      如果想從網(wǎng)絡(luò)上抓取數(shù)據(jù)存入字典,然后再對(duì)字典進(jìn)行迭代顯示,由于網(wǎng)絡(luò)I/O操作的時(shí)間相對(duì)較長(zhǎng),這樣就會(huì)造成用戶的長(zhǎng)時(shí)間等待,我們希望能一次抓取就顯示一次,于是迭代器對(duì)象出現(xiàn)了。
      在 for 循環(huán)的時(shí)候 in 后面跟的是一個(gè)可迭代對(duì)象,在循環(huán)的過(guò)程中自動(dòng)調(diào)用 iter() 將可迭代對(duì)象傳入其中,返回一個(gè)迭代器對(duì)象

      比如我們常見(jiàn)的列表和字符串都是可迭代對(duì)象,為什么呢?

      這涉及到了 Python 的魔法方法的問(wèn)題,python一切皆對(duì)象,而魔法方法就是好像是python對(duì)象的一個(gè)插件,有什么樣子的魔法方法,python 對(duì)象就會(huì)在關(guān)鍵時(shí)刻顯示某種特性(仿佛科幻小說(shuō)中主人公體內(nèi)某種隱藏的力量被激活)。迭代對(duì)象有一個(gè)魔法方法 __iter__,如果沒(méi)有這個(gè)方法,那么python 還會(huì)退而求其次,去尋找__getitem__ 這個(gè)代表他是一個(gè)序列的方法,也是可迭代的。

      迭代器對(duì)象只有一個(gè)方法就是 next(),每調(diào)用一次就會(huì)迭代一次,知道全部迭代完畢拋出異常,這其實(shí)也是for 循環(huán)的工作機(jī)制(這同時(shí)也說(shuō)明了一個(gè)問(wèn)題:迭代器內(nèi)部持有一個(gè)狀態(tài),該狀態(tài)用于記錄當(dāng)前迭代所在的位置,以方便下次迭代的時(shí)候獲取正確的元素)。


      1. l = [1,2,3,4,5,6]
      2. t = iter(l)
      3. print t.next()
      4. print t.next()
      5. print t.next()

      結(jié)果:

      1. 1
      2. 2
      3. 3

      實(shí)例:

      1. 實(shí)現(xiàn)一個(gè)迭代器對(duì)象,有next 方法每次返回一個(gè)值

      2. 實(shí)現(xiàn)一個(gè)可迭代對(duì)象 __iter__ 方法返回上面的那個(gè)迭代器對(duì)象

      實(shí)際上就是創(chuàng)建一個(gè)可迭代對(duì)象的類,實(shí)例化以后成為一個(gè)可迭代對(duì)象,然后一旦在循環(huán)中調(diào)用這個(gè)可迭代對(duì)象就能自動(dòng)調(diào)用__init__,然后實(shí)例化迭代器對(duì)象的類,這個(gè)類的實(shí)例會(huì)在迭代中不斷調(diào)用next方法。

      代碼如下:

      1. import requests
      2. from collections import Iterable,Iterator
      3. class WeatherIterator(Iterator):
      4. def __init__(self,cities):
      5. self.cities = cities
      6. self.index = 0
      7. def getWeather(self,city):
      8. r = requests.get(u"http://wthrcdn./weather_mini?city=" + city)
      9. data = r.json()['data']['forecast'][0]
      10. return '%s: %s , %s' % (city, data['low'], data['high'])
      11. def next(self):
      12. if self.index == len(self.cities):
      13. raise StopIteration
      14. city = self.cities[self.index]
      15. self.index += 1
      16. return self.getWeather(city)
      17. class WeatherIterable(Iterable):
      18. def __init__(self,cities):
      19. self.cities = cities
      20. def __iter__(self):
      21. return WeatherIterator(self.cities)
      22. for x in WeatherIterable([u"北京",u"上海",u"廣州",u"長(zhǎng)春"]):
      23. print x

      2.如何使用生成器函數(shù)實(shí)現(xiàn)可迭代對(duì)象

      那么什么是生成器?

      生成器對(duì)象其實(shí)是一種特殊的可迭代對(duì)象,他自己調(diào)用__iter__方法返回的是他自身,因此他既是一個(gè)可迭代對(duì)象,也是一個(gè)迭代器對(duì)象,而且它不需要再像上面的類一樣寫(xiě)__iter__()__next__()方法了,只需要一個(gè)yiled關(guān)鍵字(當(dāng)然你可以重寫(xiě)__iter__來(lái)實(shí)現(xiàn)自己的功能)。 (說(shuō)人話就是這個(gè)生成器的對(duì)象在每一次迭代的時(shí)候都會(huì)被yiled卡住并返回,下一次再迭代就會(huì)接著上次執(zhí)行,是不是很優(yōu)雅?)

      舉一個(gè)簡(jiǎn)單的生成器的例子:

      1. def f():
      2. print 'first'
      3. yield 1
      4. print 'second'
      5. yield 2
      6. print 'third'
      7. yield 3
      8. g = f()
      9. for x in g:
      10. print x

      結(jié)果:

      1. first
      2. 1
      3. second
      4. 2
      5. third
      6. 3

      實(shí)例:

      找出指定范圍內(nèi)的所有素?cái)?shù)

      1. class PrimeNumbers:
      2. def __init__(self,start,end):
      3. self.start = start
      4. self.end = end
      5. def isPrimeNum(self,k):
      6. if k<2:
      7. return False
      8. for x in xrange(2,k):
      9. if k % x == 0:
      10. return False
      11. return True
      12. def __iter__(self):
      13. for k in xrange(self.start,self.end+1):
      14. if self.isPrimeNum(k):
      15. yield k
      16. for x in PrimeNumbers(1,100):
      17. print x

      3.如何進(jìn)行反向迭代以及如何實(shí)現(xiàn)反向迭代

      列表的反向迭代

      (1)使用列表的反轉(zhuǎn)操作

      1. l = [1,2,3,4,5]
      2. x = l.reverse()

      但這種情況會(huì)改變?cè)斜?/p>

      (2)使用切片且步進(jìn)為-1

      1. l = [1,2,3,4,5]
      2. x = l[::-1]

      但這樣會(huì)生成一個(gè)新的列表

      (3)列表反向迭代器

      1. l = [1,2,3,4,5]
      2. for x in reversed(l):
      3. print x

      這種情況和iter()剛好是相反的,在迭代的時(shí)候會(huì)自動(dòng)調(diào)用 __reversed__對(duì)象。

      實(shí)例:

      寫(xiě)一個(gè)浮點(diǎn)數(shù)生成器,既可以正向迭代又可以反向迭代

      1. class FloatRange:
      2. def __init__(self,start,end,step):
      3. self.start = start
      4. self.end = end
      5. self.step = step
      6. def __iter__(self):
      7. t = self.start
      8. while t <= self.end:
      9. yield t
      10. t +=self.step
      11. def __reversed__(self):
      12. t = self.end
      13. while t >= self.start:
      14. yield t
      15. t -= self.step
      16. for x in FloatRange(1.0,3.0,0.5):
      17. print x
      18. print "===============cut-off rule====================="
      19. for x in reversed(FloatRange(1.0,3.0,0.5)):
      20. print x

      4.如何對(duì)迭代器做切片操作

      我們知道文本文件本身也是一個(gè)可迭代對(duì)象,每次迭代返回的是文本文件的一行,那么我們思考一個(gè)問(wèn)題,我們能不能像對(duì)列表切片一樣對(duì)文本文件切片得到一個(gè)迭代器(生成器),這樣比如我們想迭代的是100行帶300行之間的內(nèi)容就能直接迭代了。

      簡(jiǎn)單回顧文件迭代

      由于文件對(duì)象沒(méi)有__getitem__這個(gè)方法,于是沒(méi)有和列表一樣的迭代操作,那我們就可以先把文件的內(nèi)容放到一個(gè)列表里面,然后再進(jìn)行切片,如下:

      1. f = open('./LICENCE')
      2. lines = f.readlines()
      3. for x in lines[100:300]:
      4. print x

      但是這樣有一個(gè)問(wèn)題,readlines 會(huì)把文件的所有內(nèi)容都先加載到內(nèi)存里面,但是如果文件非常大,比如有幾個(gè)G大小,那么就會(huì)遇到內(nèi)存不足的問(wèn)題,于是我們只能選擇使用

      1. for line in f:
      2. print line,

      注意:如果文件指針此時(shí)已經(jīng)在文件的末尾,你是循環(huán)不出內(nèi)容的,我們還需要將使用 f.seek(0),將文件指針還原回去

      因此我們迫切的需要將文件變成一個(gè)迭代器。

      1. from itertools import islice
      2. f = open('./LICENCE')
      3. for i in islice(f,100,300):
      4. print i

      如果是想得到前100行的迭代器

      1. from itertools import islice
      2. f = open('./LICENCE')
      3. for i in islice(f,100):
      4. print i

      如果想得到從100行開(kāi)始到最后的迭代器

      1. from itertools import islice
      2. f = open('./LICENCE')
      3. for i in islice(f,100,None):
      4. print i

      注意: islice() 雖然看上去是從100開(kāi)始的,但是前99行實(shí)際上也迭代了,因此下一次使用的時(shí)候注意還原。

      5.如何在一個(gè)for 語(yǔ)句中迭代多個(gè)可迭代對(duì)象

      1.并行迭代

      比如 語(yǔ)數(shù)外三科成績(jī)分別存儲(chǔ)在3個(gè)列表中,我們現(xiàn)在需要同時(shí)迭代三個(gè)列表取出三個(gè)成績(jī),并計(jì)算總成績(jī)

      最簡(jiǎn)單的我們可以使用索引的方式

      1. from random import randint
      2. chinese = [randint(60,100) for i in xrange(40)]
      3. math = [randint(60,100) for i in xrange(40)]
      4. english = [randint(60,100) for i in xrange(40)]
      5. for x in xrange(len(math)):
      6. print chinese[x]+math[x]+english[x]

      但是這個(gè)方法有局限性,因?yàn)椴⒉皇撬械目傻鷮?duì)象都支持索引的方法訪問(wèn)其中的元素

      高階推薦:zip()

      zip() 中能傳入多個(gè)可迭代對(duì)象并將其逐項(xiàng)合并成一個(gè)元組列表,然后我們就能使用元組拆包的方式進(jìn)行迭代

      1. from random import randint
      2. chinese = [randint(60,100) for i in xrange(40)]
      3. math = [randint(60,100) for i in xrange(40)]
      4. english = [randint(60,100) for i in xrange(40)]
      5. grade = []
      6. for c,m,e in zip(chinese,math,english):
      7. grade.append(c+m+e)
      8. print grade

      2.串行

      比如每個(gè)班的英語(yǔ)成績(jī)放在一個(gè)列表中,現(xiàn)在想迭代全年級(jí)的英語(yǔ)成績(jī),找出分?jǐn)?shù)高于90分的人數(shù)

      使用 itertools 的 chain 可以多個(gè)可迭代對(duì)象進(jìn)行串行連接

      1. from random import randint
      2. from itertools import chain
      3. e1 = [randint(60,100) for i in xrange(40)]
      4. e2 = [randint(60,100) for i in xrange(40)]
      5. e3 = [randint(60,100) for i in xrange(40)]
      6. e4 = [randint(60,100) for i in xrange(40)]
      7. count = 0
      8. for x in chain(e1,e2,e3,e4):
      9. if x > 90:
      10. count += 1

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多