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 next0 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.


Related articles: