ホームページ >バックエンド開発 >Python チュートリアル >Python におけるオブジェクトの反復と反復防止のテクニックの概要
1. 反復可能オブジェクトと反復子オブジェクトを実装するには?
実際のケース
あるソフトウェアはネットワークから各都市の匂い情報を取得し、次に表示する必要があります:
北京: 15 ~ 20 天津: 17 ~ 22 长春: 12 ~ 18 ......
すべての都市の天気を一度に取得し、次に表示されると、最初の都市の温度が表示されます。これには、時間のかかるアクセス戦略を使用し、すべての都市の温度をオブジェクトにカプセル化したいと考えています。どうやって解決するのか?
解決策
反復子オブジェクト Weatherlterator
を実装し、next
メソッドは毎回都市の気温を返し、反復可能オブジェクト Weatherlterable
を実装します。 ,————iter__ メソッドは反復子オブジェクトを返します Weatherlterator
,next
方法每次返回一个城市气温,实现一个可迭代对象Weatherlterable
,————iter__方法返回一个迭代器对象
import requests from collections import Iterable, Iterator # 气温迭代器 class WeatherIterator(Iterator): 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): if self.index == len(self.cities): raise StopIteration city = self.cities[self.index] self.index += 1 return self.getWeather(city) # 可迭代对象 class WeatherIterable(Iterable): def __init__(self, cities): self.cities = cities def __iter__(self): return WeatherIterator(self.cities) for x in WeatherIterable(['北京', '上海', '广州', '深圳']): print(x)
执行结果如下:
C:\Python\Python35\python.exe E:/python-intensive-training/s2.py 北京:低温 21℃ , 高温 30℃ 上海:低温 23℃ , 高温 26℃ 广州:低温 26℃ , 高温 34℃ 深圳:低温 27℃ , 高温 33℃ Process finished with exit code 0
二、如何使用生成器函数实现可迭代对象?
实际案例
实现一个可迭代对象的类,它能迭代出给定范围内所有素数:
python pn = PrimeNumbers(1, 30) for k in pn: print(k) `` 输出结果text 2 3 5 7 11 13 17 19 23 29 “`
解决方案
-将该类的__iter__
方法实现生成器函数,每次yield
返回一个素数
class PrimeNumbers: def __init__(self, start, stop): self.start = start self.stop = stop 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.stop + 1): if self.isPrimeNum(k): yield k for x in PrimeNumbers(1, 20): print(x)
运行结果
C:\Python\Python35\python.exe E:/python-intensive-training/s3.py 2 3 5 7 11 13 17 19 Process finished with exit code 0
三、如何进行反向迭代以及如何实现反向迭代?
实际案例
实现一个连续浮点数生成器FloatRange
(和rrange
类似),根据给定范围(start
, stop
)和步进值(step
)产生一些列连续浮点数,如迭代FloatRange(3.0,4.0,0.2)
可产生序列:
正向:3.0 > 3.2 > 3.4 > 3.6 > 3.8 > 4.0 反向:4.0 > 3.8 > 3.6 > 3.4 > 3.2 > 3.0
解决方案
实现反向迭代协议的__reversed__
方法,它返回一个反向迭代器
class FloatRange: def __init__(self, start, stop, step=0.1): self.start = start self.stop = stop self.step = step def __iter__(self): t = self.start while t <= self.stop: yield t t += self.step def __reversed__(self): t = self.stop while t >= self.start: yield t t -= self.step print("正相迭代-----") for n in FloatRange(1.0, 4.0, 0.5): print(n) print("反迭代-----") for x in reversed(FloatRange(1.0, 4.0, 0.5)): print(x)
输出结果
C:\Python\Python35\python.exe E:/python-intensive-training/s4.py 正相迭代----- 1.0 1.5 2.0 2.5 3.0 3.5 4.0 反迭代----- 4.0 3.5 3.0 2.5 2.0 1.5 1.0 Process finished with exit code 0
四、如何对迭代器做切片操作?
实际案例
有某个文本文件,我们想都去其中某范围的内容,如100~300行之间的内容,python中文本文件是可迭代对象,我们是否可以使用类似列表切片的方式得到一个100~300行文件内容的生成器?
解决方案
使用标准库中的itertools.islice
,它能返回一个迭代器对象切片的生成器
from itertools import islice f = open('access.log') # # 前500行 # islice(f, 500) # # 100行以后的 # islice(f, 100, None) for line in islice(f,100,300): print(line)
islice每次训话都会消耗之前的迭代对象
l = range(20) t = iter(l) for x in islice(t, 5, 10): print(x) print('第二次迭代') for x in t: print(x)
输出结果
C:\Python\Python35\python.exe E:/python-intensive-training/s5.py 5 6 7 8 9 第二次迭代 10 11 12 13 14 15 16 17 18 19 Process finished with exit code 0
五、如何在一个for语句中迭代多个可迭代对象?
实际案例
1、某班学生期末考试成绩,语文、数学、英语分别存储再3个列表中,同时迭代三个列表,计算每个学生的总分(并行)
2、某年纪有四个班,某次考试没班英语成绩分别存储在四个列表中,依次迭代每个列表,统计全学年成绩高于90分人数(串行)
解决方案
并行:使用内置函数zip
,它能将多个可迭代对象合并,每次迭代返回一个元组
from random import randint # 申城语文成绩,# 40人,分数再60-100之间 chinese = [randint(60, 100) for _ in range(40)] math = [randint(60, 100) for _ in range(40)] # 数学 english = [randint(60, 100) for _ in range(40)] # 英语 total = [] for c, m, e in zip(chinese, math, english): total.append(c + m + e) print(total)
执行结果如下:
C:\Python\Python35\python.exe E:/python-intensive-training/s6.py [232, 234, 259, 248, 241, 236, 245, 253, 275, 238, 240, 239, 283, 256, 232, 224, 201, 255, 206, 239, 254, 216, 287, 268, 235, 223, 289, 221, 266, 222, 231, 240, 226, 235, 255, 232, 235, 250, 241, 225] Process finished with exit code 0
串行:使用标准库中的itertools.chain
from random import randint from itertools import chain # 生成四个班的随机成绩 e1 = [randint(60, 100) for _ in range(40)] e2 = [randint(60, 100) for _ in range(42)] e3 = [randint(60, 100) for _ in range(45)] e4 = [randint(60, 100) for _ in range(50)] # 默认人数=1 count = 0 for s in chain(e1, e2, e3, e4): # 如果当前分数大于90,就让count+1 if s > 90: count += 1 print(count)
実行結果は次のとおりです:
C:\Python\Python35\python.exe E:/python-intensive-training/s6.py 48 Process finished with exit code 0
2. ジェネレーター関数を使用して反復可能なオブジェクトを実装するにはどうすればよいですか?
実際のケース
指定された範囲内のすべての素数を反復処理できる反復可能オブジェクトのクラスを実装します:rrreee
yield
は毎回素数を返します🎜🎜🎜rrreee🎜🎜🎜🎜実行結果🎜🎜🎜🎜rrreee🎜🎜🎜🎜🎜 3.逆方向反復を実行する方法と逆反復を実装する方法は? 🎜🎜🎜🎜🎜実際のケース🎜🎜🎜🎜 指定された範囲 (startFloatRange
(rrange
と同様) を実装します。 /code> code>、stop
) およびステップ値 (step
) は、FloatRange(3.0,4.0,0.2 の反復など) の一連の連続する浮動小数点数を生成します。 )
シーケンスを生成できます: 🎜🎜🎜rrreee🎜🎜🎜🎜ソリューション🎜🎜🎜逆反復プロトコルの __reversed__
メソッドを実装し、逆反復子を返します🎜🎜🎜🎜rrreee🎜 🎜🎜🎜出力結果🎜🎜🎜🎜rrreee🎜🎜🎜🎜🎜 4. イテレータでスライス操作を実行するにはどうすればよいですか? 🎜🎜🎜🎜🎜実際のケース🎜🎜🎜🎜 特定のテキストファイルがあり、100〜300行のコンテンツなどの特定の範囲のコンテンツを削除したいのですが、Pythonのテキストファイルは反復可能なオブジェクトです。リストのスライスと同様の方法で、100 ~ 300 行のファイル コンテンツのジェネレーターを取得しますか? 🎜🎜🎜解決策🎜🎜🎜標準ライブラリの itertools.islice
を使用します。これにより、反復子オブジェクトのスライスのジェネレーターを返すことができます🎜🎜🎜🎜rrreee🎜🎜🎜islice は、各トレーニングの前に消費されます。反復可能なオブジェクト🎜🎜🎜rrreee🎜🎜🎜🎜出力結果🎜🎜🎜🎜rrreee🎜🎜🎜🎜🎜 5. for ステートメントで複数の反復可能なオブジェクトを反復するにはどうすればよいですか? 🎜🎜🎜🎜🎜実際のケース🎜🎜🎜🎜1. あるクラスの生徒の期末試験の結果、中国語、数学、英語がそれぞれ 3 つのリストに保存され、3 つのリストが同時に反復処理されて、各生徒の合計スコア (並列) 🎜 🎜🎜 2. ある年齢には 4 つのクラスがあり、あるテストの各クラスの英語のスコアは 4 つのリストに格納され、人数をカウントするために反復されます。学年全体で 90 点を超えるスコアを持つ (シリアル) 🎜🎜🎜🎜解決策 解決策 🎜🎜🎜並列: 複数の反復可能なオブジェクトをマージしてタプルを返すことができる組み込み関数 zip
を使用します。各反復ごとに 🎜🎜🎜🎜rrreee🎜🎜🎜🎜 実行結果は次のとおりです: 🎜🎜 🎜🎜rrreee🎜🎜🎜 Serial: 標準ライブラリの itertools.chain
を使用します。これにより、複数の反復可能オブジェクトを接続できますObjects rreee outputsummary🎜🎜🎜🎜上記は、この記事の全体的な内容ですご質問がございましたら、メッセージを残して連絡してください。 🎜🎜Python のオブジェクト反復と反反復のテクニックをまとめた関連記事をさらに詳しく知りたい場合は、PHP 中国語 Web サイトに注目してください。 🎜🎜🎜🎜