shinemic

groupby_test.py

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