如何在一个for语句中迭代多个可迭代对象?

需求:
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\tjzka'  # 之前的切割字符串的例子可以通过chain来做

>>> s.split(';')
['abc', '123|xyz', '678|fweuow\tjzka']

>>> 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\tjzka']]

>>> list(chain(*[['abc'], ['123', 'xyz'], ['678', 'fweuow\tjzka']]))
['abc', '123', 'xyz', '678', 'fweuow\tjzka']

>>> from functools import reduce

>>> list(reduce(lambda it_s, sep: chain(*map(lambda ss:ss.split(sep),it_s)), ';|\t',[s]))
['abc', '123', 'xyz', '678', 'fweuow', 'jzka']

>>> 

posted @ 2020-07-08 22:59  Richardo-M-Lu  阅读(137)  评论(0编辑  收藏  举报