Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from itertools import groupby
- from operator import itemgetter
- from collections import namedtuple
- s = [1, 2, 3, 5, 8, 9, 10]
- # 为将上述列表分割为“连续”的三个子列表: [[1, 2, 3], [5], [8, 9, 10]]
- # 注意到定义这个分割子列表需满足:后继-前驱=1
- # 一个非循环的思路为同步生成一个上升序列,与原列表作差值:
- # 1 2 3 5 8 9 10
- # 0 1 2 3 4 5 6
- # --------------
- # 1 1 1 2 4 4 4
- # 观察到这个“连续”被量化了,即选取这些差值连续的值即可
- # itertools.groupby 可以实现这样的效果,将连续出现的相同值归到一组
- for k, v in groupby(enumerate(s), lambda x: x[1] - x[0]):
- # 利用 enumerate 生成一个“陪跑”的上升序列
- # 每次迭代出来的形式为一个元组 (i, v)
- # 其中 i 为 enumerate 带来的序号,v 为原列表中对应位置的值
- # 所以需要把值中可与序号作差的部分进行作差,在这里由于列表比较简单,直接作差即可
- # 由 groupby 产生的 k 就是上面注释中提到的差值,v 表示被归组的迭代对象
- # 由 v 返回迭代器,用一次就没了,先将迭代器铺开到 val
- val = list(v)
- print(k, val)
- # 但实际上,这个差值对我们来说没有任何用处,所以需要后续的提取操作
- # 下面的写法与列表推导式同理:[_val[1] for _val in val]
- print(k, list(map(itemgetter(1), val)))
- print('-' * 40)
- # 当然实际情况不会这么简单,需要归组的一般是个对象
- Data = namedtuple('Data', ('sequence', 'amount'))
- _data = [
- ['A', 100.00],
- ['B', 200.00],
- ['C', 300.00],
- ['E', 5000.00],
- ['H', 10000.00],
- ['I', 11000.00],
- ['J', 12000.00],
- ['T', 50000.00],
- ['X', 80000.00],
- ['Y', 80000.00],
- ]
- data = list(map(Data._make, _data))
- for dat in data[:5]:
- print(dat.sequence, dat.amount)
- print('-' * 40)
- for k, v in groupby(enumerate(data), lambda x: ord(x[1].sequence) - x[0]):
- print('->'.join(map(lambda x: f"({x.sequence}, {x.amount})",
- map(itemgetter(1), v))))
Add Comment
Please, Sign In to add comment