1. 程式人生 > >Python物件迭代與反迭代相關問題與解決技巧

Python物件迭代與反迭代相關問題與解決技巧

 

1.如何實現可迭代物件和迭代器物件(1)

In [1]:
# 列表和字串都是可迭代物件

l = [1,2,3,4]
In [2]:
s = 'abcde'
In [3]:
for
x in l:print(x)
 
1
2
3
4
In [4]:
for x in s:print(x)
 
a
b
c
d
e
In [5]:
iter(l)
Out[5]:
<list_iterator at 0x7fde5571c208>
In [6]:
iter
(s)
Out[6]:
<str_iterator at 0x7fde5571c710>
In [7]:
l.__iter__()
Out[7]:
<list_iterator at 0x7fde5571ca90>
In [8]:
# 迭代器物件

t = iter(l)
In [9]:
next(t)
Out[9]:
1
In [10]:
next(t)
Out[10]:
2
In [11]:
next(t)
Out[11]:
3
In [12]:
t2 = iter(s)
In [13]:
next(t2)
Out[13]:
'a'
In [14]:
next(t2)
Out[14]:
'b'
 

2.如何實現可迭代物件和迭代器物件(2)

 

''' 從網路抓取各個城市氣溫,並依次顯示: 北京:12-16 上海:20-30 ... 如果一次抓取所有城市天氣再顯示,顯示第一個城市氣溫時,有很高的延時,並且浪費儲存空間,我們期望以'用時訪問的策略', 並且能把所有城市氣溫封裝到一個物件裡,可用for語句進行迭代,如何解決? '''

In [15]:
import requests

def getWeather(city):
    '''獲取一個城市氣溫'''
    r = requests.get('http://wthrcdn.etouch.cn/weather_mini?city=' + city)
    data = r.json()['data']['forecast'][0]
    
    return '%s:%s,%s' %(city,data['low'],data['high'])
In [16]:
getWeather('北京')
Out[16]:
'北京:低溫 -7℃,高溫 0℃'
In [17]:
getWeather('上海')
Out[17]:
'上海:低溫 8℃,高溫 10℃'
In [18]:
from collections import Iterable,Iterator
In [19]:
# 可迭代物件抽象介面
Iterable.__abstractmethods__
Out[19]:
frozenset({'__iter__'})
In [20]:
# 迭代器物件抽象介面
Iterator.__abstractmethods__
Out[20]:
frozenset({'__next__'})
In [21]:
import requests
from collections import Iterable,Iterator

class WeatherIterator(Iterator):
    '''實現一個迭代器物件WeatherIterator'''
    def __init__(self,cities):
        self.cities = cities
        #記錄迭代位置
        self.index = 0
    
    def getWeather(self,city):
        '''獲取單個城市氣溫資料'''
        r = requests.get('http://wthrcdn.etouch.cn/weather_mini?city=' + city)
        data = r.json()['data']['forecast'][0]
        return '%s:%s,%s' %(city,data['low'],data['high'])
        
    def __next__(self):
        '''__next__方法每次返回一個城市氣溫'''
        if self.index == len(self.cities):
            raise StopIteration
        city = self.cities[self.index]
        self.index += 1
        return self.getWeather(city)
    
class WeatherIterable(Iterable):
    '''實現一個可迭代物件WeatherIterable'''
    def __init__(self,cities):
        self.cities = cities
        
    def __iter__(self):
        '''__iter__方法返回一個迭代器物件'''
        return WeatherIterator(self.cities)
In [22]:
for city in WeatherIterable(['北京','上海','廣州','深圳']):
    print(city)
 
北京:低溫 -7℃,高溫 0℃
上海:低溫 8℃,高溫 10℃
廣州:低溫 9℃,高溫 13℃
深圳:低溫 12℃,高溫 15℃
 

3.如何使用生成器函式實現可迭代物件

 

''' 實際案例: 實現一個可迭代物件的類,它能迭代出給定範圍內的所有素數: pn = PrimeNumber(1, 30) for k in pn: print k

輸出結構: 2 3 5 7 11 13 17 19 23 29

解決方案: 將該類的iter方法實現成生成器函式,每次yield返回一個素數 '''

In [23]:
def f():
    print('in f(),1')
    yield 1
    
    print('in f(),2')
    yield 2
    
    print('in f(),3')
    yield 3
    
g = f()

print(g.__next__())
print(g.__next__())
print(g.__next__())
 
in f(),1
1
in f(),2
2
in f(),3
3
In [24]:
'''生成器物件即實現了可迭代物件介面,又實現了迭代器介面'''

g = f()
for x in g:
    print(x)
 
in f(),1
1
in f(),2
2
in f(),3
3
In [25]:
g.__iter__() is g
Out[25]:
True
In [26]:
# 使用生成器返回所有素數

class PrimeNumbers:
    def __init__(self,start,end):
        self.start = start
        self.end = end
        
    def isPrimeNum(self,k):
        if k < 2:
            return False
        
        for i in range(2,k):
            if k % i == 0:
                return False
        return True
    
    def __iter__(self):
        for k in range(self.start,self.end+1):
            if self.isPrimeNum(k):
                yield k
In [27]:
for x in PrimeNumbers(1,100):
    print(x)
 
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
53
59
61
67
71
73
79
83
89
97
 

4.如何進行反向迭代以及如何實現反向迭代

 

''' 實際案例: 實現一個連續浮點數發生器FloatRange(和xrange類似), 根據給定範圍(start, end)和步進值(step)產生一系列連續浮點數, 如迭代FloatRange(3.0, 4.0, 0.2)可產生序列 '''

In [28]:
l = [1,2,3,4,5]
In [29]:
l.reverse()# 會改變原列表
In [30]:
# 切片操作,返回新的列表,但是浪費資源
l1 = l[::-1]
In [31]:
# 列表的反向迭代器,與iter()對應
reversed(l)
Out[31]:
<list_reverseiterator at 0x7fde55721358>
In [32]:
for x in reversed(l):
    print(x)
 
1
2
3
4
5
In [33]:
# 實現正向和反向連續浮點序列
class FloatRange:
    def __init__(self,start,end,step=0.1):
        self.start = start
        self.end = end
        self.step = step
        
    #正向迭代器
    def __iter__(self):
        t = self.start
        while t<= self.end:
            yield t
            t += self.step
            
    #反向迭代器   
    def __reversed__(self):
        t = self.end
        while t >= self.start:
            yield t
            t -= self.step
In [34]:
for x in FloatRange(1.0,4.0,0.5):
    print(x)
 
1.0
1.5
2.0
2.5
3.0
3.5
4.0
In [35]:
for x in reversed(FloatRange(1.0,4.0,0.5)):
    print(x)
 
4.0
3.5
3.0
2.5
2.0
1.5
1.0
 

5.如何對迭代器做切片操作

In [36]:
f = open('Alice.txt')
In [37]:
ls_lines = f.readlines()
# 會把檔案指標移動到了檔案最後
cut_lines = ls_lines[1:5]
print(cut_lines)
# readlines會把整個檔案匯入到記憶體當中,檔案過大時會出現記憶體不足
 
['she hadpeeped into the book her sister was reading, but it had nopictures or conversations in it, `and what is the use \n', "of a book,'thought Alice `without pictures or conversation?'So she was considering in her own mind (as well as she \n", 'could,for the hot day made her feel very sleepy and stupid), whetherthe pleasure of making a daisy-chain would be worth \n', 'the troubleof getting up and picking the daisies, when suddenly a WhiteRabbit with pink eyes ran close by her.There was \n']
In [38]:
# islice能返回一個迭代物件切片的生成器
from itertools import islice

islice(f,100,300)
Out[38]:
<itertools.islice at 0x7fde54cdcf48>
In [39]:
f.seek(0)# 把檔案指標移動到檔案最前
for line in islice(f,20,25):
    print(line)
 
Alice to herself, `after such a fall as this, Ishall think nothing of tumbling down stairs!  How brave they'llall think 

me at home!  Why, I wouldn't say anything about it,even if I fell off the top of the house!' (Which was very 

likelytrue.)Down, down, down.  Would the fall NEVER come to an end!  `Iwonder how many miles I've fallen by this time?' 

she said aloud.`I must be getting somewhere near the centre of the earth.  Letme see:  that would be four thousand 

miles down, I think--' (for,you see, Alice had learnt several things of this sort in herlessons in the schoolroom, and 

In [40]:
islice(f,30)#前30行
islice(f,50,None)#50-最後一行
Out[40]:
<itertools.islice at 0x7fde54cca598>
In [41]:
l = range(20)
In [42]:
#生成l的迭代器
t = iter(l)
In [43]:
#每次使用islice時,要重新申請一個可迭代物件,它會消耗這個迭代物件的資源
for x in islice(t,5,10):
    print(x)
 
5
6
7
8
9
In [44]:
#t已經迭代到位置10
for x in t:
    print(x)
 
10
11
12
13
14
15
16
17
18
19
 

6.如何在一個for語句中迭代多個可迭代物件

 

''' 實際案例: 1.某班學生期末成績,語文,數學,英語分別儲存在3個列表中, 同時迭代三個列表,計算每個學生的總分.(並行)

解決方案: 並行: 使用內建函式zip,它能將多個可迭代物件合併,每次迭代返回一個元組. '''

In [45]:
from random import randint

chinese = [randint(60,100) for _ in range(40)]
math = [randint(60,100) for _ in range(40)]
english = [randint(60,100) for _ in range(40)]
In [46]:
# 使用索引
# 侷限:如果不是列表,而是生成器的話,將不能用索引訪問
t = []
for i in range(len(chinese)):
    t.append(chinese[i] + math[i] + english[i])
    
print(t)
 
[211, 198, 246, 238, 237, 244, 263, 217, 242, 226, 266, 238, 272, 249, 249, 222, 221, 265, 249, 234, 216, 213, 245, 236, 243, 239, 253, 244, 239, 264, 226, 231, 246, 255, 245, 236, 221, 229, 249, 217]
In [47]:
# 使用zip()函式
total = []
for c,m,e in zip(chinese,math,english):
    total.append(c + m + e)
    
print(total)
 
[211, 198, 246, 238, 237, 244, 263, 217, 242, 226, 266, 238, 272, 249, 249, 222, 221, 265, 249, 234, 216, 213, 245, 236, 243, 239, 253, 244, 239, 264, 226, 231, 246, 255, 245, 236, 221, 229, 249, 217]
 

''' 實際案例: 2.某年及有4個班,某次考試每班英語成績分別儲存在4個列表中, 依次迭代每個列表,統計全學年成績高於90分人數.(序列)

解決方案: 序列: 使用標準庫中的itertools.chain,它能將多個可迭代物件連線. '''

In [48]:
from random import randint
from itertools import chain


c1 = [randint(60,100) for _ in range(40)]
c2 = [randint(60,100) for _ in range(41)]
c3 = [randint(60,100) for _ in range(42)]
c4 = [randint(60,100) for _ in range(43)]

count = 0

for s in chain(c1,c2,c3,c4):
    if s > 90:
        count += 1
In [49]:
count
Out[49]:
37
Python物件相關問題解決技巧

  1.如何實現可迭代物件和迭代器物件(1)¶ In [1]: # 列表和字

3. 物件相關問題解決技巧

一. 如何實現可迭代物件和迭代器物件 實際案列 某軟體要求, 從網路抓取各個城市氣溫資訊, 並依次顯示: 北京: 15-20 天津: 17-22 長春: 12-18 ... 如果一次抓取所有城市氣溫再顯示, 顯示第一個城市氣溫時, 有很高

Python序列化序列化-jsonpickle

day 存儲 什麽 pychar odi 兩個 對象 .cn 序列化                        Python序列化與反序列化-json與pickle                                             作者:尹正傑 版

python】一文弄懂器iteror(__next__)物件iterable物件

一、定義區別 剛開始學的經常會被迭代器與可迭代物件弄混淆,下面清晰的介紹兩者的不同。 迭代器 Iterator (物件):如果一個物件同時擁有__iter__  和 __next__方法的(物件),也就是說可以被next()函式呼叫並不斷返回下一個值的物件稱為迭

Python生成器,器,可物件

              在瞭解Python的資料結構時,容器(container)、可迭代物件(iterable)、迭代器(iterator)、生成器(generator)、列表/集合/字典推導式(list,set,dic

python-第一類物件,閉包,

# def fn(): # print("我叫fn") # fn() # print(fn) # <function fn at 0x0000000001D12E18> # fn() # gn = fn # 函式名可以進行賦值 # print(gn) # gn() # fn =

【ES6】物件

ES6 新的陣列方法、集合、for-of 迴圈、展開運算子(...)甚至非同步程式設計都依賴於迭代器(Iterator )實現。本文會詳解 ES6 的迭代器與生成器,並進一步挖掘可迭代物件的內部原理與使用方法 一、迭代器的原理 在程式語言中處理陣列或集合時,使用迴圈語句必須要初始化一個變數記錄迭

python之路---11 第一類物件 函式名 閉包

二十九.   1.函式名的運用      ①函式名是⼀個變數, 但它是⼀個特殊的變數, 與括號配合可以執⾏函式的變數    ②函式名是一個記憶體地址      ③ 函式名可以賦值給其他變數           &nbs

python,可物件,生成器,器--

python迭代 給定一個list或tuple,我們可以通過for迴圈來遍歷這個list或tuple,這種遍歷我們稱為迭代(Iteration) 可迭代物件: List:for a in List dict:(因為dict的儲存不是按照list的方式順序

一張圖明白python 生成器/器/可物件 之間的關係

python中迭代器與生成器,相信學的時候,很多小夥伴都會感到頭疼,一會迭代器,一會生成器,一會可迭代物件,一會可迭代物件用iter方法轉換成迭代器.......,有沒有感覺像是繞口令,那麼久讓我告訴你Python中什麼是迭代器和生成器吧......... 本文的組織如

器 可物件 詳解 python iterator

1.迭代器(iterator),是可以用直接用for 或其他迭代工具遍歷的東西。2.可迭代物件(iterable),先需要內建函式iter()轉化成迭代器,然後才可以用for或其他迭代工具遍歷。常見的可迭代物件有list,set,dict,range物件(python3)等3

Python中的生成器(generator)和器(Iterator)

Python是一種動態的程式語言,那就具有動態程式語言的特性,可以在執行時改變其結構,比如新的函式,物件、程式碼也可以引進,已有的函式可以被刪除。。。目前最常用的可以歸納為以下幾點:1.執行的過程中給物件繫結(新增)屬性,2.執行過程中給類繫結(新增)屬性,3.執行的過程中給類繫結(新增)方法,4.

吳伯凡-自我自我的第一步--》模式識別(第一天更新)

自我迭代 什麼是自我迭代 簡單的講自我迭代就是對自己的認知系統,進行持續系統的優化 那怎麼樣進行自我迭代呢? 自我迭代的第一步就是,要找準自己的定位,說的大白話一些,就是要認清自己是那塊料,古人不是常說人貴有自知之明嘛,說的就是這個意思 而比較好的教育方式,是因材施教,而這要求老師有能力去發現每個學

Python(七)語法 高階特性 切片 | (迴圈)| 列表生成式 | 生成器 |

切片 取一個list或tuple的部分元素是非常常見的操作 有一個list[0,1,2,3,4,5]如果我們要取前n個元素比如說3個數 一般做法是 >>> L=[] >>> n=3 >>> for i in range(n): .

反向器reverse_iterator正向器iterator之間的轉換(以及例項應用)

反向迭代器     相信大家對正向迭代器應該都很熟悉,然而對於反向迭代器的使用確是有幾處需要注意的地方,在此記錄一下。先看STL原始碼處註釋如下: /** * Bidirectional and random access iterators have c

Python基礎之(裝飾器,器、生成器)

一、裝飾器 1.1、什麼是裝飾器? 裝飾器本質上就是一個python函式,他可以讓其他函式在不需要做任何程式碼變動的前提下,增加額外的功能,裝飾器的返回值也是一個函式物件。 1.2、裝飾器的原則  不修改被裝飾物件的原始碼 不修改被裝飾物件的呼叫方式 1.3、裝飾器的目標

二分法Python程式碼實現,和非

1 看程式碼吧, #用迭代實現二分法 #寫個類吧 class Solution: def binarySearch(self, nums, target): return self.search(nums, 0, len(nums) - 1, target) de

python全棧開發- 前⽅⾼能-器 python_day_12

今日主要內容 1, 函式名的應用,第一類物件 函式名可以像變數一樣進行使用 1.賦值 2.作為list元素 3.作為引數 4.作為返回值 2, 閉包 內部函式訪問外部函式的區域性變數. 好處: 1.安全 2.常駐記憶體. 提高效率 3, 迭代器 可迭代物件(Itera

python器&生成器使用技巧(1):遍歷、代理、生成器建立、反向

1. 手動遍歷迭代器 next() 遍歷一個可迭代物件中的所有元素,但是卻不想使用for迴圈。為了手動的遍歷可迭代物件,使用 next() 函式並在程式碼中捕獲 StopIteration 異常。 通常來講, StopIteration 用來指示迭代的結尾。 然而,如果手動

遞迴、、動態規劃的區別聯絡

一、定義 遞迴:程式呼叫自身,從頂部將問題分解,通過解決掉所有分解出來的小問題,來解決整個問題。 迭代:利用變數的原值推算出變數的一個新值。遞迴中一定有迭代,但是迭代中不一定有遞迴。 動態規劃:通常與遞迴相反,其從底部開始解決問題。將所有小問題解決掉,進而解決的