English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Sommario delle tecniche di iterazione e anti-iterazione degli oggetti in Python

Come implementare l'oggetto iterable e l'oggetto iteratore?

Caso reale

Un software richiede di prelevare le informazioni di odore delle città da Internet e poi visualizzarle:

Pechino: 15 ~ 20 Tianjin: 17 ~ 22 Changchun: 12 ~ 18 ......

Se si prelevano tutte le temperature urbane in una volta e si visualizzano, c'è un ritardo molto alto nel visualizzare la temperatura della prima città e si spreca molto spazio di archiviazione. Speriamo di adottare una strategia di accesso in tempo e di encapsulare tutte le temperature urbane in un oggetto, che possa essere iterato con una sentenza for. Come risolvere questo problema?

Soluzione

Implementare un oggetto iteratore Weatherlterator, il metodo next restituisce una temperatura urbana, implementare un oggetto iterable Weatherlterable, il metodo iter__ restituisce un oggetto iteratore

import requests from collections import Iterable, Iterator # Iteratore di temperatura 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) # Oggetto iterabile class WeatherIterable(Iterable): def __init__(self, cities): self.cities = cities def __iter__(self): return WeatherIterator(self.cities) for x in WeatherIterable(['北京', '上海', '广州', '深圳']): print(x)

I risultati dell'esecuzione sono i seguenti:

C:\Python\Python35\python.exe E:/python-intensive-training/s2.py Pechino: temperatura minima 21°C, temperatura massima 30°C Shanghai: temperatura minima 23°C, temperatura massima 26°C Guangzhou: temperatura minima 26°C, temperatura massima 34°C Shenzhen: temperatura minima 27°C, temperatura massima 33°C Process finished with exit code 0

Due: come implementare un oggetto iterabile utilizzando una funzione generatrice?

Caso reale

Implementazione di una classe di oggetti iterabili che può iterare tutti i numeri primi entro un intervallo dato:

python pn = PrimeNumbers(1, 30) for k in pn: print(k) `` Output result text
2 3 5 7 11 13 17 19 23 29
“`

Soluzione

-Implementazione della funzione generatrice __iter__ della classe, che restituisce un numero primo ogni volta che viene chiamata 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)

Risultato dell'esecuzione

C:\Python\Python35\python.exe E:/python-intensive-training/s3.py 2 3 5 7 11 13 17 19 Processo terminato con codice di uscita 0

Come eseguire l'iterazione inversa e come implementarla?

Caso reale

Implementazione di un generatore di numeri reali consecutivi FloatRange (simile a rrange), che genera una serie di numeri reali consecutivi in base all'intervallo (start, stop) e al passo (step), ad esempio iterando FloatRange(3.0, 4.0, 0.2) si può generare la sequenza:

In senso positivo: 3.0 > 3.2 > 3.4 > 3.6 > 3.8 > 4.0 In senso negativo: 4.0 > 3.8 > 3.6 > 3.4 > 3.2 > 3.0

Soluzione

Implementazione del metodo __reversed__ per il protocollo di iterazione inversa, che restituisce un iteratore inverso

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("Iterazione in senso positivo-----") for n in FloatRange(1.0, 4.0, 0.5): print(n) print("Iterazione in senso negativo-----") for x in reversed(FloatRange(1.0, 4.0, 0.5)): print(x)

Risultato dell'output

C:\Python\Python35\python.exe E:/python-intensive-training/s4.py Iterazione positiva----- 1.0 1.5 2.0 2.5 3.0 3.5 4.0 Iterazione negativa----- 4.0 3.5 3.0 2.5 2.0 1.5 1.0 Processo terminato con codice di uscita 0

Quarto, come eseguire un'operazione di slice sugli iteratori?

Caso reale

Abbiamo un file di testo, e vogliamo ottenere il contenuto di una certa gamma, come le righe tra 100 e 300, Python i file di testo sono oggetti iterabili, possiamo ottenere un generatore del contenuto del file tra 100 e 300 righe come modo di tagliare una lista?

Soluzione

Utilizzando il generatore islice della libreria standard itertools, può restituire un generatore di oggetti iterabili di slice

from itertools import islice f = open('access.log') # # Le prime 500 righe # islice(f, 500) # # Le 100 righe successive # islice(f, 100, None) per riga in islice(f, 100, 300): print(riga)

islice consuma l'oggetto di iterazione precedente ogni volta che viene chiamato

l = range(20) t = iter(l) per x in islice(t, 5, 10): print(x) print('Second iteration') per x in t: print(x)

Risultato dell'output

C:\Python\Python35\python.exe E:/python-intensive-training/s5.py 5 6 7 8 9 Seconda iterazione 10 11 12 13 14 15 16 17 18 19 Process finished with exit code 0

V, come iterare più oggetti iterabili in una singola istruzione for?

Caso reale

1, i punteggi finali degli studenti di una classe, cinese, matematica e inglese sono memorizzati in tre liste separate, iterando contemporaneamente tre liste, calcolando il punteggio totale di ciascuno studente (in parallelo)

2, ci sono quattro classi in una certa età, e i punteggi di esame in inglese di ciascuna classe sono memorizzati in quattro liste separate, iterando ciascuna lista, contando il numero di studenti con punteggi superiori a 90 nel corso dell'intero anno (in serie)

Soluzione

Parallelismo: l'uso della funzione built-in zip, che può combinare più oggetti iterabili, restituendo un tuple per ogni iterazione

from random import randint # Valori di punteggio cinese, 40 persone, punteggio tra 60-100 chinese = [randint(60, 100) for _ in range(40)] math = [randint(60, 100) for _ in range(40)] # Matematica english = [randint(60, 100) for _ in range(40)] # Inglese total = [] for c, m, e in zip(chinese, math, english): total.append(c + m + e) print(total)

I risultati dell'esecuzione sono i seguenti:

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

Serie: utilizzare il chain della libreria standard, che può connettere più oggetti iterabili

from random import randint from itertools import chain # Generare punteggi casuali per quattro classi 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)] # Numero di studenti predefinito = 1 count = 0 for s in chain(e1, e2, e3, e4): # Se il punteggio corrente è maggiore di 90, count + 1 if s > 90: count += 1 print(count)

Risultato dell'output

C:\Python\Python35\python.exe E:/python-intensive-training/s6.py 48 Process finished with exit code 0

Sommario

Questo è tutto il contenuto dell'articolo, spero possa aiutare tutti a imparare o lavorare meglio. Se avete domande, potete lasciare un commento per discuterle.

Ti potrebbe interessare