python 진급: 제2장(대상 교체와 반교체)
문제1: 어떻게 교체 가능한 대상과 교체기 대상을 실현합니까?
문제 내용: 모 소프트웨어는 인터넷에서 각 도시의 날씨 정보를 캡처하고 순서대로 현식: 북강:15~20상하이:20~26항주:17~27...만약에 모든 도시의 날씨를 한 번에 잡고 다시 표시하면 첫 번째 도시의 기온을 나타낼 때 매우 높은 지연 시간이 있고 저장 공간을 낭비한다.우리는'시간적 접근'전략(하나씩 잡고 하나씩 표시)으로 모든 도시의 기온을 한 대상에 봉할 수 있고 for문구로 교체할 수 있기를 기대한다. 어떻게 해결합니까?
우리는 이제 교체 가능한 대상과 교체기 대상을 알아보자. iter () 방법이나 getitem () 방법이 포함된 대상을 교체 가능한 대상이라고 부른다.우리는 Python에 내장된hasattr () 함수를 사용하여 대상이 교체될 수 있는지 아닌지를 판단할 수 있다.
>>> hasattr((), '__iter__')
True
>>> hasattr([], '__iter__')
True
>>> hasattr({}, '__iter__')
True
>>> hasattr(123, '__iter__')
False
>>> hasattr('abc', '__iter__')
False
>>> hasattr('abc', '__getitem__')
True
또한 isinstance()를 사용하여 다음과 같이 판단할 수 있습니다.
>>> from collections import Iterable
>>> isinstance((), Iterable) #
True
>>> isinstance([], Iterable) #
True
>>> isinstance({}, Iterable) #
True
>>> isinstance('abc', Iterable) #
True
>>> isinstance(100, Iterable) #
False
교체기는 교체기 프로토콜(iterator protocol)을 따르는 대상 교체기 프로토콜(iterator protocol)을 말한다. 대상을 실현하려는iter()와next() 방법(주의:Python3은next() 방법)을 말한다. 그 중에서iter() 방법은 교체기 대상 자체를 되돌려주고,next() 방법은 용기의 다음 요소를 되돌려주며 후속 요소가 없을 때StopIteration 이상을 던진다.
교체 가능한 대상은 목록, 문자열 등 순환할 수 있는 것을 가리킨다.교체기 대상은 교체 가능한 대상이iter() 한석을 통해 생성되는 대상을 말한다.
In [1]: iter?
Docstring:
iter(iterable) -> iterator
iter(callable, sentinel) -> iterator
Get an iterator from an object. In the first form, the argument must
supply its own iterator, or be a sequence.
In the second form, the callable is called until it returns the sentinel.
Type: builtin_function_or_method
In [2]: l = [1,2,3,4]
In [3]: s = 'abcde'
In [17]: l.__iter__()
Out[17]:
In [18]: iter(l)
Out[18]:
iter() __iter__()
In [5]: iter(s)
Out[5]:
소결: 모듈, 목록, 사전, 문자열의 대상은 교체할 수 있지만 교체기는 아니지만 iter () 함수를 통해 교체기 대상을 얻을 수 있습니다.Python의 for 순환은 실질적으로 내장 함수iter()를 통해 교체기를 얻은 다음next() 함수를 계속 호출하여 이루어진다.사용자 정의 교체기는 대상을 실현하는 iter ()와next () 방법 (주의: Python3은next () 방법을 실현해야 합니다). 그 중에서 iter () 방법은 교체기의 대상 자체를 되돌려주고, next () 방법은 용기의 다음 요소를 되돌려주며, 후속 요소가 없을 때StopIteration 이상을 던집니다.
읽을 시간이 있어요http://wiki.jikexueyuan.com/project/explore-python/Advanced-Features/iterator.html
해결 방안: 단계1: 하나의 교체기 대상인 Weather Iterator를 실현하고,next 방법은 한 도시의 기온을 되돌릴 수 없다. 단계2: 교체 가능한 대상인 Weather Iterable을 실현하고,iter 방법은 교체기 대상을 되돌려준다.
import requests
from collections import Iterable,Iterator
# def getweather(city):
# r = requests.get(u'http://wthrcdn.etouch.cn/weather_mini?citykey=' + city)
# data = r.json()['data']['forecast'][0]
# return '%s: %s , %s' % (city, data['low'],data['high'])
class WeatherIterator(Iterator):
def __init__(self,citys):
self.citys = citys
self.index = 0
def getweather(self,city):
r = requests.get(u'http://wthrcdn.etouch.cn/weather_mini?citykey=' + city)
data = r.json()['data']['forecast'][0]
return '%s: %s , %s' % (r.json()['data']['city'], data['low'], data['high'])
#python3
def __next__(self):
if self.index == len(self.citys):
raise StopIteration
city = self.citys[self.index]
self.index += 1
return self.getweather(city)
class WeatherIterable(Iterable):
def __init__(self,citys):
self.citys = citys
def __iter__(self):
return WeatherIterator(self.citys)
# :101010100
# :101210101
# :101020100
# :101280101
for weather in WeatherIterable(['101010100','101210101','101020100','101280101']):
print(weather)
결과 출력:
: 11℃ , 24℃
: 18℃ , 27℃
: 15℃ , 21℃
: 21℃ , 26℃
이곳의 API는 내가 사용하는 도시 인코딩이다.
문제2: 어떻게 생성기 함수를 사용하여 교체 가능한 대상을 실현합니까?
질문 내용: 주어진 범위 내의 모든 소수를 교체할 수 있는 클래스를 실현합니다: pn = Prime Numbers(1,30) for k in pn: print(k) 출력 결과: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29
해결 방안: 이 종류의iter 방법을 생성기 함수로 실현하고 yield마다 소수를 되돌려줍니다.
In [21]: def f():
...: print("in f(),1")
...: yield 1
...: print("in f(),2")
...: yield 2
...: print("in f(),3")
...: yield 3
...:
In [22]: g = f()
In [23]: next(g)
in f(),1
Out[23]: 1
In [24]: next(g)
in f(),2
Out[24]: 2
In [25]: next(g)
in f(),3
Out[25]: 3
In [26]: next(g)
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
in ()
----> 1 next(g)
StopIteration:
생성기는 지난번에 실행된 위치를 기억할 것입니다. 교체기와 마찬가지로 점차적으로 교체되며, 마지막에 StopIteration을 보고합니다.
In [34]: for x in g:
...: print(x)
...:
in f(),1
1
in f(),2
2
in f(),3
3
g는 교체 가능한 대상이고 g의iter () 함수로 생성된 교체기는 그 자체이다.
In [28]: g.__iter__() is g
Out[28]: True
교체기와 생성기의 행동은 일치한다.이곳의 g는 iter도 포함하고,next 인터페이스도 포함한다.
우리는 교체 대상의iter 방법을 생성기 함수로 실현하여 함수가 호출될 때 직접 운행하지 않고next 방법을 포함하는 생성기 대상을 되돌려줍니다.
class PrimeNumber:
def __init__(self,start,end):
self.start = start
self.end = end
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.end + 1):
if self.isPrimeNum(k):
yield k
for x in PrimeNumber(1,100):
print(x)
문제3: 어떻게 역방향 교체를 진행하고 어떻게 역방향 교체를 실현합니까?
문제 내용: 연속 부동점수 발생기 플로트 랭크(range와 유사)를 실현하고 지정된 범위(start,end)와 스텝 값(step)에 따라 일련의 연속 부동점수를 생성한다. 예를 들어 플로트 랭크(3.0,4.0,0.2)를 교체하면 순서가 발생한다. 정방향: 3.0-> 3.2-> 3.4-> 3.6-> 3.6-> 3.8-> 4.0 역방향: 4.0-> 3.8-> 3.6-> 3.4-> 3.4-> 3.2-> 3.2-> 3.0-3.0
In [1]: l = [1,2,3,4,5]
In [2]: l.reverse()
reverse() ,
In [3]: l
Out[3]: [5, 4, 3, 2, 1]
In [4]: l = [1,2,3,4,5]
In [5]: l[::-1]
Out[5]: [5, 4, 3, 2, 1]
In [6]: l
Out[6]: [1, 2, 3, 4, 5]
reversed()
In [7]: reversed(l)
Out[7]:
iter()
In [8]: iter(l)
Out[8]:
In [9]: for x in reversed(l):
...: print(x)
...:
5
4
3
2
1
__iter__
In [10]: l.__iter__
Out[10]:
__reversed__
In [11]: l.__reversed__?
Docstring: L.__reversed__() -- return a reverse iterator over the list
Type: builtin_function_or_method
해결 방안: 역방향 교체 프로토콜을 실현하는reversed 방법으로 역방향 교체기를 되돌려줍니다.
class FloatRange:
def __init__(self,start,end,step=0.1):
self.start = start
self.end = end
self.step = step
def __iter__(self):
t = self.start
while t <= self.end:
yield t
t += self.step
def __reversed__(self):
t = self.end
while t >= self.start:
yield t
t -= self.step
#
for x in FloatRange(1.0,4.0,0.5):
print(x)
#
for x in reversed(FloatRange(1.0,4.0,0.5)):
print(x)
문제5: 어떻게 교체기에 대해 절편 조작을 진행합니까?
문제 내용: 어떤 텍스트 파일이 있습니다. 우리는 그 중 어느 범위 내의 내용, 예를 들어 100300줄 사이의 내용만 읽고 싶습니다.python에서 텍스트 파일은 교체 대상입니다. 목록 슬라이드와 같은 방식으로 100300줄 파일 내용의 생성기를 얻을 수 있습니까?
f = open("/var/log/dmesg") f[100:300] # 가능합니까?
In [19]: f = open("/var/log/dmesg",'r')
In [20]: for lin in f:
...: print(lin)
...:
해결 방안: 표준 라이브러리의itertools를 사용합니다.islice, 교체 대상 슬라이드의 생성기를 되돌려줍니다.
In [19]: f = open("/var/log/dmesg",'r')
In [20]: from itertools import islice
In [20]: from itertools import islice
In [21]: islice?
Init signature: islice(self, /, *args, **kwargs)
Docstring:
islice(iterable, stop) --> islice object
islice(iterable, start, stop[, step]) --> islice object
Return an iterator whose next() method returns selected values from an
iterable. If start is specified, will skip all preceding elements;
otherwise, start defaults to zero. Step defaults to one. If
specified as another value, step determines how many values are
skipped between successive calls. Works like a slice() on a list
but returns an iterator.
Type: type
In [22]: islice(f,100,300)
Out[22]:
In [23]: for line in islice(f,100,300):
...: print(line)
500
In [24]: islice(f,500)
Out[24]:
500
In [25]: islice(f,100,None)
Out[25]:
주의해라, islice () 함수는 교체 대상에 손실이 있다.
In [26]: l = range(20)
In [27]: l
Out[27]: range(0, 20)
In [28]: t = iter(l)
In [29]: t
Out[29]:
In [30]: for x in islice(t,5,10):
...: print(x)
...:
5
6
7
8
9
In [31]: for x in t:
...: print(x)
...:
10
11
12
13
14
15
16
17
18
19
우리는 islice () 를 사용할 때 t (앞의 것을 버리고) 를 소모하고, 다시 교체할 때 남은 것만 교체할 수 있습니다.
문제6: 어떻게 한 for문장에서 여러 개의 교체 가능한 대상을 교체합니까
문제 내용: 1. 한 반 학생의 기말고사 성적, 국어, 수학, 영어는 각각 3개의 목록에 저장되고 동시에 3개의 목록을 교체하여 각 학생의 총점을 계산한다.(병행)2, 모 학년에는 4개 반이 있는데 매번 시험마다 4개 반에 영어 성적이 각각 4개의 리스트에 저장되어 순서대로 각 리스트를 교체하여 전체 학년 성적이 90점보다 높은 인원을 통계한다.(직렬)
In [32]: from random import randint
In [33]: chinese = [ randint(60,100) for _ in range(40)]
In [34]: math = [ randint(60,100) for _ in range(40)]
In [35]: english = [ randint(60,100) for _ in range(40)]
In [36]: for i in range(len(math)):
...: print(chinese[i] + math[i] + english[i])
위의 방식은 색인 지원에만 적합하며, 생성기라면 지원되지 않습니다.
솔루션:
병렬: 내장 함수 zip을 사용하면 여러 개의 교체 가능한 대상을 합쳐서 매번 교체할 때마다 하나의 원조를 되돌려줍니다.직렬: 표준 라이브러리의itertools를 사용합니다.chain, 여러 개의 교체 가능한 대상을 연결할 수 있습니다.
병렬 상태:
In [7]: zip([1,2,3,4],('a','b','c','d'))
Out[7]:
In [8]: list(zip([1,2,3,4],('a','b','c','d')))
Out[8]: [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')]
In [9]: total = [ ]
In [10]: for c,m,e in zip(chinese,math,english):
...: total.append(c + m + e)
...:
In [11]: total
Out[11]:
[193,
243,
256,
260,
216,
246,
257,
241,
224,
240,
200,
244,
274,
240,
250,
230,
234,
224,
233,
222,
217,
242,
268,
266,
233,
227,
247,
247,
227,
227,
259,
248,
260,
238,
247,
251,
203,
297,
211,
244]
직렬 상태:
In [12]: from itertools import chain
In [13]: chain?
Init signature: chain(self, /, *args, **kwargs)
Docstring:
chain(*iterables) --> chain object
Return a chain object whose .__next__() method returns elements from the
first iterable until it is exhausted, then elements from the next
iterable, until all of the iterables are exhausted.
Type: type
In [15]: for x in chain([1,2,3,4],['a','b','c','d']) :
...: print(x)
...:
1
2
3
4
a
b
c
d
우리는 직렬 통계 성적이 90보다 많은 인원을 보았다.
In [16]: e1 = [ randint(60,100) for _ in range(40)]
In [17]: e2 = [ randint(60,100) for _ in range(42)]
In [18]: e3 = [ randint(60,100) for _ in range(42)]
In [19]: e4 = [ randint(60,100) for _ in range(45)]
In [20]: count = 0
In [21]: for s in chain(e1,e2,e3,e4):
...: if s > 90:
...: count += 1
...:
In [22]: count
Out[22]: 39
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.