kachayev / fn.py

Functional programming in Python: implementation of missing features to enjoy FP
Other
3.35k stars 204 forks source link

Implement traditional group-by as found in most other languages like clojure/scala/ruby/etc #39

Closed sbinq closed 10 years ago

sbinq commented 10 years ago

This default group-by logic is different from what is called groupby within itertools.

aavezel commented 10 years ago
from itertools import groupby
lst = ['1', '12', 'a', '123', 'ab']
keyfunc = lambda x: len(x)
for k, g in groupby(sorted(lst, key=keyfunc), key=keyfunc):
    print k
    print list(g)
kachayev commented 10 years ago

@aavezel The main problem with given solution is that we need to calculate keyfunc(item) twice of each item in lst (it can be problematic if keyfunc is something more sophisticated than len).

sbinq commented 10 years ago

@aavezel @kachayev yes, agree with @kachayev arguments against itertools.groupby. Also don't like the idea of having to write such boilerplate (well, not much - but still a little annoying) and convert manually to dict.

aavezel commented 10 years ago

@kachayev : you are mistake. itertools.groupby return iterators, and not calculate keys if it not needed. It is more suitable for principle of lazy calculation.

kachayev commented 10 years ago

@aavezel

  1. sorted function returns a list, not iterable. So there is no room for lazy calculation.
  2. In your code keyfunc will be evaluated for each element by sorted function (cause it's necessary to compare items on sorting) and then it be evaluated by groupby function to return you k value and find out the boundaries of each group.
sbinq commented 10 years ago

@kachayev updated code according to your review - styling issues and more explicit test

kachayev commented 10 years ago

@sbinq Thanks for your contribution!