需求:
1、某班学生期末考试成绩,语言、数学、英语分别存储在3个列表中,同时迭代三个列表,计算每个学生的总分。(并行)
2、某年级有4个班,某次考试每班英语成绩分别存储在4个列表中,依次迭代每下列表,统计全年级成绩高于90分的人数(串行)
思路:
并行:使用内置函数zip,它能将多个可迭代对象合并,每次迭代返回一个元组
串行:使用标准库中itertools chain,它能将多个可迭代对象连接
代码:
from itertools import chain
from random import randint
#模拟并行
#生成一个班的语文、数学、英语成绩
chinese = [ randint(60,100) for _ in range(40)]
math = [ randint(60,100) for _ in range(40)]
english = [ randint(60,100) for _ in range(40)]
#方法一:通过索引来实现并行,但是如果对象不是可迭代对象而是迭代器会有问题,不推荐
# for i in range(len(math)):
# rint(chinese[i] + math[i] + English[i])
#方法二:使用zip来实现算出每个学生的总分,zip(iter1 [,iter2 [...]]) --> zip object,returns a tuple where the i-th element comes from the i-th iterable argument
total = []
for c,m,e in zip(chinese,math,english):
total.append(c+m+e)
print(total)
print('='*30)
#模拟串行
#生成四个班的英语成绩
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)]
#统计四个班中英语成绩高于80分的人数,chain(*iterables) --> chain object returns elements from the first iterable until it is exhausted, then elements from the next iterable, until all of the iterables are exhausted.
count = 0
for x in chain(e1,e2,e3,e4):
if x > 80:
count += 1
print(count)
==================================================================
>>> from random import randint
>>> chinese = [ randint(60,100) for _ in range(20) ]
>>> chinese
[69,
73,
83,
88,
90,
80,
97,
100,
64,
99,
92,
64,
66,
94,
94,
75,
60,
91,
91,
85]
>>> math = [ randint(60,100) for _ in range(20) ]
>>> english = [ randint(60,100) for _ in range(20) ]
>>> zip?
Init signature: zip(self, /, *args, **kwargs)
Docstring:
zip(iter1 [,iter2 [...]]) --> zip object
Return a zip object whose .__next__() method returns a tuple where
the i-th element comes from the i-th iterable argument. The .__next__()
method continues until the shortest iterable in the argument sequence
is exhausted and then it raises StopIteration.
Type: type
Subclasses:
>>> zip([1,2,3],[4,5,6])
<zip at 0x7fafadd0ed48>
>>> list(zip([1,2,3],[4,5,6]))
[(1, 4), (2, 5), (3, 6)]
>>> list(zip([1,2,3],[4,5,6],[7,8,9]))
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
>>> list(zip([1,2,3],[4,5,6],[7,8]))
[(1, 4, 7), (2, 5, 8)]
>>> t = []
>>> for s1,s2,s3 in zip(chinese,math,english):
... t.append(s1+s2+s3)
...
>>> t
[226,
230,
240,
228,
262,
218,
237,
266,
206,
246,
231,
225,
213,
264,
270,
231,
246,
240,
225,
236]
>>> [ sum(s) for s in zip(chinese,math,english) ]
[226,
230,
240,
228,
262,
218,
237,
266,
206,
246,
231,
225,
213,
264,
270,
231,
246,
240,
225,
236]
>>> list(map(sum,zip(chinese,math,english)))
[226,
230,
240,
228,
262,
218,
237,
266,
206,
246,
231,
225,
213,
264,
270,
231,
246,
240,
225,
236]
>>> list(map(lambda s1,s2,s3:s1+s2+s3,chinese,math,english))
[226,
230,
240,
228,
262,
218,
237,
266,
206,
246,
231,
225,
213,
264,
270,
231,
246,
240,
225,
236]
>>> map(lambda *args:args,chinese,math,english) # 这个和zip函数的功能是一样的
<map at 0x7fafadf202e8>
>>> list(map(lambda *args:args,chinese,math,english))
[(69, 82, 75),
(73, 76, 81),
(83, 90, 67),
(88, 70, 70),
(90, 96, 76),
(80, 73, 65),
(97, 65, 75),
(100, 87, 79),
(64, 62, 80),
(99, 75, 72),
(92, 65, 74),
(64, 68, 93),
(66, 77, 70),
(94, 72, 98),
(94, 76, 100),
(75, 63, 93),
(60, 93, 93),
(91, 64, 85),
(91, 64, 70),
(85, 65, 86)]
>>> list(zip(chinese,math,english))
[(69, 82, 75),
(73, 76, 81),
(83, 90, 67),
(88, 70, 70),
(90, 96, 76),
(80, 73, 65),
(97, 65, 75),
(100, 87, 79),
(64, 62, 80),
(99, 75, 72),
(92, 65, 74),
(64, 68, 93),
(66, 77, 70),
(94, 72, 98),
(94, 76, 100),
(75, 63, 93),
(60, 93, 93),
(91, 64, 85),
(91, 64, 70),
(85, 65, 86)]
>>> from itertools import chain
>>> 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
Subclasses:
>>> for x in chain([1,2,3],[4,5,6,7],[7,8,9]):
... print(x)
...
1
2
3
4
5
6
7
7
8
9
>>> c1 = [randint(60,100) for _ in range(20)]
>>> c2 = [randint(60,100) for _ in range(20)]
>>> c3 = [randint(60,100) for _ in range(23)]
>>> c4 = [randint(60,100) for _ in range(25)]
>>> len([ x for x in chain(c1,c2,c3,c4) if x > 90])
22
>>> s = 'abc;123|xyz;678|fweuow jzka' # 之前的切割字符串的例子可以通过chain来做
>>> s.split(';')
['abc', '123|xyz', '678|fweuow jzka']
>>> list(map(lambda ss, ss.split('|'),s.split(';')))
File "<ipython-input-70-40392777dfc9>", line 1
list(map(lambda ss, ss.split('|'),s.split(';')))
^
SyntaxError: invalid syntax
>>> list(map(lambda ss: ss.split('|'),s.split(';')))
[['abc'], ['123', 'xyz'], ['678', 'fweuow jzka']]
>>> list(chain(*[['abc'], ['123', 'xyz'], ['678', 'fweuow jzka']]))
['abc', '123', 'xyz', '678', 'fweuow jzka']
>>> from functools import reduce
>>> list(reduce(lambda it_s, sep: chain(*map(lambda ss:ss.split(sep),it_s)), ';| ',[s]))
['abc', '123', 'xyz', '678', 'fweuow', 'jzka']
>>>