Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import itertools
- from itertools import groupby
- from operator import itemgetter
- testdata = [
- {
- 'Elements' : [
- { 'Type': 't', 'Id': 1 },
- { 'Type': 'u', 'Id': 2 },
- { 'Type': 't', 'Id': 3 },
- { 'Type': 'u', 'Id': 1 },
- ]
- },
- {
- 'Elements' : [
- { 'Type': 'u', 'Id': 1 },
- { 'Type': 't', 'Id': 2 },
- { 'Type': 'u', 'Id': 3 },
- { 'Type': 't', 'Id': 1 },
- { 'Type': 'u', 'Id': 2 },
- ]
- },
- ]
- flat = sum((f['Elements'] for f in testdata), [])
- sflat = sorted(flat, key=lambda e: (e['Type'], e['Id']))
- gflat = [list(g) for k, g in groupby(sflat, key=lambda e: (e['Type'], e['Id']))]
- #print("Grouped:")
- result = [ list(g) for kf in (itemgetter('Type', 'Id'),)
- for _, g in groupby(sorted(sum((f['Elements'] for f in testdata), []), key=kf), key=kf) ]
- assert result == gflat
- #print(result)
- def _extractor_func(extractor, kwargs):
- def _ident(x):
- return x
- if extractor:
- if len(extractor) > 1:
- raise TypeError('Too many positional arguments. Only 1 allowed.')
- return extractor[0]
- if not kwargs:
- return _ident
- if len(kwargs) != 1:
- raise TypeError('Too many named parameters. Only 1 allowed.')
- for var, code in kwargs.items():
- return eval('lambda {}: {}'.format(var, code))
- def select_many(seq, *extractor, **kw):
- extract = _extractor_func(extractor, kw)
- for item in seq:
- for val in extract(item):
- yield val
- def group_by(seq, *extractor, **kw):
- extract = _extractor_func(extractor, kw)
- for key, group in itertools.groupby(sorted(seq, key=extract), key=extract):
- yield list(group)
- flat2 = list(select_many(testdata, f = "f['Elements']"))
- assert flat2 == flat
- result2 = group_by(flat2, e = "e['Type'], e['Id']")
- assert result2 == result2
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement