上面的答案很好,但不容易理解。不幸的是,如 1_CR 所指出的那样,z
从后面开始打印其中一个可读列表将消耗迭代器。groupby
这又是解决方案,但打印了中间步骤。从逻辑上讲,从z3
需要开始的所有步骤在每次打印后都需要重新完成。
from operator import itemgetter, mul
from itertools import groupby
from functools import reduce
import copy
z1 = [(1,4),(3,5),(2,9),(6,23),(3,21),(2,66),(5,20),(1,33),(3,55),(1,8)]
print('data: ', z1)
z2 = sorted(z1, key=itemgetter(0))
print('sorted: ', z2)
z3 = groupby(z2, key=itemgetter(0))
print('grouped:', [(x, list(y)) for x,y in z3])
z3 = groupby(z2, key=itemgetter(0))
z4 = ((key, list(value for (key, value) in groups)) for (key, groups) in z3)
print('lumped: ', list(z4))
z3 = groupby(z2, key=itemgetter(0))
z4 = ((key, list(value for (key, value) in groups)) for (key, groups) in z3)
z5 = ((key, reduce(mul, values, 1)) for (key, values) in z4 if len(values) > 1)
print('reduced:', list(z5))
z3 = groupby(z2, key=itemgetter(0))
z4 = ((key, list(value for (key, value) in groups)) for (key, groups) in z3)
z5 = ((key, reduce(mul, values, 1)) for (key, values) in z4 if len(values) > 1)
z6 = sum(value for (key, value) in z5)
print('sum: ', z6)
这就是这一切的回报。我认为这真的有助于理解发生了什么。函数式编程可以很有趣,只要您了解会发生什么。
data: [(1, 4), (3, 5), (2, 9), (6, 23), (3, 21), (2, 66), (5, 20), (1, 33), (3, 55), (1, 8)]
sorted: [(1, 4), (1, 33), (1, 8), (2, 9), (2, 66), (3, 5), (3, 21), (3, 55), (5, 20), (6, 23)]
grouped: [(1, [(1, 4), (1, 33), (1, 8)]), (2, [(2, 9), (2, 66)]), (3, [(3, 5), (3, 21), (3, 55)]), (5, [(5, 20)]), (6, [(6, 23)])]
lumped: [(1, [4, 33, 8]), (2, [9, 66]), (3, [5, 21, 55]), (5, [20]), (6, [23])]
reduced: [(1, 1056), (2, 594), (3, 5775)]
sum: 7425