"""
Iterable
Iterator
requests
len
"""# 如何實現可迭代對象和迭代器對象?# Iterable 可迭代對象的基類;Iterator 迭代器對象(一次性,用完就沒了,不可再生,不同的迭代器互不干擾)的基類from collections import Iterable, Iterator
import requests
# url = 'http://wthrcdn.etouch.cn/weather_mini?city=深圳'# r = requests.get(url)# r.json()# print(r.text)
l =[1,2,3,4,5,6]classWeatherIterator(Iterator):def__init__(self, cities):
self.cities = cities
self.index =0def__next__(self):if self.index ==len(self.cities):raise StopIteration
city = self.cities[self.index]
self.index +=1return self.get_weather(city)defget_weather(self, city):
url ='http://wthrcdn.etouch.cn/weather_mini?city='+ city
r = requests.get(url)
data = r.json()['data']['forecast'][0]return city, data['high'], data['low']classWeatherIterable(Iterable):def__init__(self, cities):
self.cities = cities
def__iter__(self):return WeatherIterator(self.cities)defshow(w):for x in w:print(x)
w = WeatherIterable(['深圳',['廣州'],['南寧']]*10)
show(w)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
2. 如何使用生成器函數實現可迭代對象?
"""
collections,Iterable
map
all
range
yield
"""# 如何使用生成器函數實現可迭代對象?# 將該類的__iter__方法實現成生成器函數,每次yield返回一個素數。deff():print('in f 1')yield1print('in f 2')yield2print('in f 3')yield3from collections import Iterable
classPrimeNumbers(Iterable):def__init__(self, a, b):
self.a = a
self.b = b
def__iter__(self):for k inrange(self.a, self.b):if self.is_prime(k):yield k
defis_prime(self, k):returnFalseif k <2elseall(map(lambda x: k % x,range(2, k)))# if k < 2:# return False## # [2, k-1]# # for x in range(2, k):# # if k % x == 0:# # return False# all(map(lambda x: k % x, range(2, k)))# return Truedefmy_test(a, b):for k inrange(a, b):if is_prime(k):yield k
defis_prime(k):returnFalseif k <2elseall(map(lambda x: k % x,range(2, k)))
pn = my_test(1,30)for n in pn:print(n)
"""
itertools,islice
enumerate
range
list
有某個文本文件,我們想讀取其中某範圍的內容如100~300行之間的內容,python中文件是可迭代對象,我們是否可以使用類似列表切片的方式得到一個100~300行文件內容的生成器?
"""# 如何對可迭代對象做切片操作?
l =list(range(10))
g = l[3]# 等價於:
l.__getitem__(3)# 切片重載下列方法
l.__getitem__(slice(2,8))
l.__getitem__(slice(2,8,2))# 解決方案:使用itertools.islice,它能返回一個迭代對象切片的生成器。from itertools import islice
# f = open('')# for line in islice(f, 100 - 1, 300):# print(line)defmy_islice(iterable, start, end, step=1):
tmp =0for i, x inenumerate(iterable):if i >= end:breakif i >= start:if tmp ==0:
tmp = step
yield x
tmp -=1print(list(my_islice(range(100,200),10,20,3)))print(list(islice(range(100,200),10,20,3)))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
5. 如何在一個for語句中迭代多個可迭代對象?
"""
random,randint
range
zip
append
sum
map
list
chain
reduce
"""# 如何在一個for語句中迭代多個可迭代對象?# 方案一:並行,使用內置函數zip,它能將多個可迭代對象合併,每次迭代返回一個元祖。from random import randint
chinese =[randint(60,100)for _ inrange(20)]
math =[randint(60,100)for _ inrange(20)]
english =[randint(60,100)for _ inrange(20)]
t =[]for s1, s2, s3 inzip(chinese, math, english):
t.append([s1, s2, s3])[sum(s)for s inzip(chinese, math, english)]list(map(sum,zip(chinese, math, english)))list(map(lambda s1, s2, s3: s1 + s2 + s3, chinese, math, english))list(map(lambda*args: args, chinese, math, english))list(zip(chinese, math, english))# 串行:使用標準庫中的itertools.chain, 它能將多個可迭代對象連接。from itertools import chain
c1 =[randint(60,100)for _ inrange(20)]
c2 =[randint(60,100)for _ inrange(20)]
c3 =[randint(60,100)for _ inrange(20)]
c4 =[randint(60,100)for _ inrange(20)]len([x for x in chain(c1, c2, c3, c4)if x >90])
s ='abc\ka;dak,asldf\t5475|dslf:sdl/kjf'list(map(lambda ss: ss.split('|'), s.split(';')))from functools importreduce
r =list(reduce(lambda it_s, sep: chain(*map(lambda ss: ss.split(sep), it_s)),'\\/;,|:\t',[s]))print(r)