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

Resumo das técnicas de iteração e anti-iteração de objetos no Python

How to implement iterable and iterator objects?

Caso real

Some software requires fetching weather information for various cities from the network and then displaying:

北京: 15 ~ 20 天津: 17 ~ 22 长春: 12 ~ 18 ......

If all city weather is fetched at once and displayed, there will be a high delay in displaying the first city temperature, and it will waste storage space. We expect a time-based access strategy, and encapsulate all city temperatures into an object, which can be iterated over with a for statement. How to solve this?

Solução

Implement a iterator object Weatherlterator, next method returns a city temperature, implement a iterable object Weatherlterable,————iter__ method returns an iterator object

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

Os resultados da execução são os seguintes:

C:\Python\Python35\python.exe E:/python-intensivo-treinamento/s2.py Pequim: baixa temperatura 21℃ , alta temperatura 30℃ Shanghai: baixa temperatura 23℃ , alta temperatura 26℃ Guangzhou: baixa temperatura 26℃ , alta temperatura 34℃ Shenzhen: baixa temperatura 27℃ , alta temperatura 33℃ Processo finalizado com código de saída 0

II, como usar funções geradoras para implementar objetos iteráveis?

Caso real

Implementa uma classe de objeto iterável que pode iterar todos os números primos dentro do intervalo fornecido:

python pn = PrimeNumbers(1, 30) for k in pn: print(k) `` Resultado de saída text
2 3 5 7 11 13 17 19 23 29
“`

Solução

-Implementa o método __iter__ da classe, gerando uma função geradora a cada yield que retorna um número primo

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)

Resultados da execução

C:\Python\Python35\python.exe E:/python-intensivo-treinamento/s3.py 2 3 5 7 11 13 17 19 Processo finalizado com código de saída 0

III, como realizar iterações reversas e como implementar iterações reversas?

Caso real

Implementa um gerador contínuo de números de ponto flutuante FloatRange (semelhante a rrange), que gera uma série de números de ponto flutuante contínuos com base no intervalo fornecido (start, stop) e no valor de passo (step), como iteração FloatRange(3.0,4.0,0.2) pode gerar uma sequência:

Direcional:3.0 > 3.2 > 3.4 > 3.6 > 3.8 > 4.0 Reversa:4.0 > 3.8 > 3.6 > 3.4 > 3.2 > 3.0

Solução

implementa o protocolo de iteração reversa com o método __reversed__, que retorna um iterador reverso

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("Iteração direta-----") for n in FloatRange(1.0, 4.0, 0.5): print(n) print("Reversão-----") for x in reversed(FloatRange(1.0, 4.0, 0.5)): print(x)

Resultado da saída

C:\Python\Python35\python.exe E:/python-intensivo-treinamento/s4.py Forward iteration----- 1.0 1.5 2.0 2.5 3.0 3.5 4.0 Reversão----- 4.0 3.5 3.0 2.5 2.0 1.5 1.0 Process finished with exit code 0

Quatro, como fazer operações de fatiamento em iteradores?

Caso real

Existe um arquivo de texto, queremos extrair o conteúdo de um determinado intervalo, por exemplo100~300 linhas de conteúdo, os arquivos de texto em python são objetos iteráveis. Podemos usar a maneira de fatiar lista semelhante para obter um100~300 linhas de conteúdo do arquivo gerador?

Solução

Usando o módulo padrão itertools.islice, ele pode retornar um gerador de objeto cortador de iterador

from itertools import islice f = open('access.log') # # Antes500 linhas # islice(f, 500) # # 100 linhas posteriores # islice(f, 100, None) for line in islice(f,10)300): print(line)

islice sempre consome o objeto iterável anterior

l = range(20) t = iter(l) for x in islice(t, 5, 10): print(x) print('Segunda iteração') for x in t: print(x)

Resultado da saída

C:\Python\Python35\python.exe E:/python-intensivo-treinamento/s5.py 5 6 7 8 9 Segunda iteração 10 11 12 13 14 15 16 17 18 19 Processo finalizado com código de saída 0

Cinco, como iterar múltiplos objetos iteráveis em uma sentença for?

Caso real

1A pontuação final dos alunos de uma turma, língua chinesa, matemática e inglês são armazenados em3Em uma lista, ao mesmo tempo, iterar por três listas, calculando a pontuação total de cada aluno (paralelamente)

2Em um ano letivo, há quatro turmas. A pontuação de inglês de cada turma em um exame específico é armazenada em quatro listas diferentes. Iterar por cada lista, contando a pontuação total do ano letivo superior a90 pessoas, pontuação de 0 (cadeia)}

Solução

Paralelo: Usando a função embutida zip, que pode combinar vários objetos iteráveis, retornando um tupla em cada iteração

from random import randint # Notas de língua chinesa, # 4) 0 pessoas, a pontuação novamente60-10) chinese = [randint(6) 10) for _ in range(4) math = [randint(6) 10) for _ in range(4) # Inglês english = [randint(6) 10) for _ in range(4) # Matemática total = [] for c, m, e in zip(chinese, math, english): total.append(c + m + e) print(total)

Os resultados da execução são os seguintes:

C:\Python\Python35\python.exe E:/python-intensivo-treinamento/s6.py [232, 234, 259, 248, 241, 236, 245, 253, 275, 238, 24) 239, 283, 256, 232, 224, 201, 255, 206, 239, 254, 216, 287, 268, 235, 223, 289, 221, 266, 222, 231, 24) 226, 235, 255, 232, 235, 25) 241, 225] Processo finalizado com código de saída 0

Cadeia: Usando a biblioteca padrão itertools.chain, que pode conectar vários objetos iteráveis

from random import randint from itertools import chain # Geração de notas aleatórias de quatro turmas e1 = [randint(6) 10) for _ in range(4) e2 = [randint(6) 10) for _ in range(42)3 = [randint(6) 10) for _ in range(45)4 = [randint(6) 10) for _ in range(5) # Número de pessoas padrão=1 count = 0 for s in chain(e1, e2, e3, e4) # Se a pontuação atual for maior que90, então count+1 if s > 90: count += 1 print(count)

Resultado da saída

C:\Python\Python35\python.exe E:/python-intensivo-treinamento/s6.py 48 Processo finalizado com código de saída 0

Resumo

Isso é tudo o que há neste artigo, espero que ajude um pouco no seu aprendizado ou trabalho, se tiver alguma dúvida, pode deixar um comentário para trocar.

Você também pode gostar