Summary of techniques for object iteration and anti iteration in Python
- 2020-05-10 18:26:05
- OfStack
1. How to implement iterable objects and iterator objects?
The actual case
Some software requires to grab the odor information of each city from the network, and then display:
Beijing: 15 ~ 20 Tianjin: 17 ~ 22 Changchun: 12 ~ 18 ......
If we capture all the city's weather once and display it again, when the temperature of the first city is displayed, there is a high delay and a waste of storage space. We expect to use the time access strategy and encapsulate all the city's temperature into one object, which can be iterated by for statement. How to solve this problem?
The solution
Implement 1 iterator object
Weatherlterator
,
next
Method returns 1 city temperature at a time and implements 1 iterable object
Weatherlterable
The iter__ method returns an iterator object
import requests from collections import Iterable, Iterator # Air temperature 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) # Iterable object class WeatherIterable(Iterable): def __init__(self, cities): self.cities = cities def __iter__(self): return WeatherIterator(self.cities) for x in WeatherIterable([' Beijing ', ' Shanghai ', ' Guangzhou ', ' shenzhen ']): print(x)
The implementation results are as follows:
C:\Python\Python35\python.exe E:/python-intensive-training/s2.py Beijing: low temperature 21 ℃ , The high temperature 30 ℃ Shanghai: low temperature 23 ℃ , The high temperature 26 ℃ Guangzhou: low temperature 26 ℃ , The high temperature 34 ℃ Shenzhen: low temperature 27 ℃ , The high temperature 33 ℃ Process finished with exit code 0
2. How to implement iterable objects using generator functions?
The actual case
Implement a class of iterable objects, which can iterate out all primes in a given range:
python pn = PrimeNumbers(1, 30) for k in pn: print(k) `` The output text
2 3 5 7 11 13 17 19 23 29
" `
The solution
- will be of this class
__iter__
Method implements the generator function each time
yield
Returns a prime number
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)
The results
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
3. How to carry out the reverse iteration and how to realize the reverse iteration?
The actual case
Implement 1 continuous floating point generator
FloatRange
(and
rrange
Similarly), according to a given range (
start
,
stop
) and step values (
step
) generates a series of consecutive floating point Numbers, such as an iteration
next
0
Producible sequence:
Positive: 3.0 > 3.2 > 3.4 > 3.6 > 3.8 > 4.0 The reverse: 4.0 > 3.8 > 3.6 > 3.4 > 3.2 > 3.0
The solution
Implement the reverse iteration protocol
__reversed__
Method, which returns a reverse iterator
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(" The positive phase iteration -----") for n in FloatRange(1.0, 4.0, 0.5): print(n) print(" Inverse iteration -----") for x in reversed(FloatRange(1.0, 4.0, 0.5)): print(x)
The output
C:\Python\Python35\python.exe E:/python-intensive-training/s4.py The positive phase iteration ----- 1.0 1.5 2.0 2.5 3.0 3.5 4.0 Inverse iteration ----- 4.0 3.5 3.0 2.5 2.0 1.5 1.0 Process finished with exit code 0
4. How to slice the iterator?
The actual case
There is a text file, we want to go to a certain range of contents, such as the contents between 100 and 300 lines, python Chinese file is an iterable object, can we use the method of list slice to get a generator of the contents of the file between 100 and 300 lines?
The solution
Use the standard library
itertools.islice
, it can return an iterator object slice generator
from itertools import islice f = open('access.log') # # before 500 line # islice(f, 500) # # 100 Line later # islice(f, 100, None) for line in islice(f,100,300): print(line)
Each islice lecture consumes the previous iteration
import requests from collections import Iterable, Iterator # Air temperature 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) # Iterable object class WeatherIterable(Iterable): def __init__(self, cities): self.cities = cities def __iter__(self): return WeatherIterator(self.cities) for x in WeatherIterable([' Beijing ', ' Shanghai ', ' Guangzhou ', ' shenzhen ']): print(x)
0
The output
import requests from collections import Iterable, Iterator # Air temperature 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) # Iterable object class WeatherIterable(Iterable): def __init__(self, cities): self.cities = cities def __iter__(self): return WeatherIterator(self.cities) for x in WeatherIterable([' Beijing ', ' Shanghai ', ' Guangzhou ', ' shenzhen ']): print(x)
1
5. How to iterate over multiple iterable objects in one for statement?
The actual case
1. The final exam results of a certain class are stored in 3 lists respectively in Chinese, mathematics and English, and the 3 lists are iterated at the same time to calculate the total score of each student (in parallel).
2. There are 4 classes in a certain age, and the English scores of a certain exam without classes are stored in 4 lists respectively. Each list is iterated in turn, and the number of students with scores higher than 90 in the whole school year is counted (serial).
The solution
Parallelism: use built-in functions
zip
, which can merge multiple iterable objects, returning one tuple per iteration
import requests from collections import Iterable, Iterator # Air temperature 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) # Iterable object class WeatherIterable(Iterable): def __init__(self, cities): self.cities = cities def __iter__(self): return WeatherIterator(self.cities) for x in WeatherIterable([' Beijing ', ' Shanghai ', ' Guangzhou ', ' shenzhen ']): print(x)
2
The implementation results are as follows:
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
Serial: USES the standard library
itertools.chain
, it can connect multiple iterable objects
import requests from collections import Iterable, Iterator # Air temperature 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) # Iterable object class WeatherIterable(Iterable): def __init__(self, cities): self.cities = cities def __iter__(self): return WeatherIterator(self.cities) for x in WeatherIterable([' Beijing ', ' Shanghai ', ' Guangzhou ', ' shenzhen ']): print(x)
4
The output
import requests from collections import Iterable, Iterator # Air temperature 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) # Iterable object class WeatherIterable(Iterable): def __init__(self, cities): self.cities = cities def __iter__(self): return WeatherIterator(self.cities) for x in WeatherIterable([' Beijing ', ' Shanghai ', ' Guangzhou ', ' shenzhen ']): print(x)
5
conclusion
The above is the whole content of this article, I hope to help you with your study or work, if you have any questions, you can leave a message to communicate.