In [12]:
def group_by(iterable, key_func=None):
if key_func is None:
def key_func(x):
return x
group_by_dict = {}
for item in iterable:
key = key_func(item)
group_by_dict.setdefault(key, []).append(item)
return group_by_dict
In [13]:
group_by([1, 2, 1, 3, 2, 1])
Out[13]:
In [14]:
def group_by(iterable, key_func=lambda x: x):
group_by_dict = {}
for item in iterable:
key = key_func(item)
group_by_dict.setdefault(key, []).append(item)
return group_by_dict
In [15]:
group_by([1, 2, 1, 3, 2, 1])
Out[15]:
In [16]:
def mod3(n): return n % 3
In [18]:
numbers = [1, 4, 5, 6, 8, 19, 34, 55]
group_by(numbers, key_func=mod3)
Out[18]:
In [19]:
from operator import itemgetter
import unittest
class GroupByTests(unittest.TestCase):
"""Tests for group_by."""
def test_test_tuples_of_strings(self):
animals = [
('agatha', 'dog'),
('kurt', 'cat'),
('margaret', 'mouse'),
('cory', 'cat'),
('mary', 'mouse'),
]
animals_by_type = {
'mouse': [('margaret', 'mouse'), ('mary', 'mouse')],
'dog': [('agatha', 'dog')],
'cat': [('kurt', 'cat'), ('cory', 'cat')],
}
output = group_by(animals, key_func=itemgetter(1))
self.assertEqual(output, animals_by_type)
def test_strings(self):
words = ["Apple", "animal", "apple", "ANIMAL", "animal"]
word_groups = {
"apple": ["Apple", "apple"],
"animal": ["animal", "ANIMAL", "animal"],
}
output = group_by(words, key_func=str.lower)
self.assertEqual(output, word_groups)
# To test the Bonus part of this exercise, comment out the following line
# @unittest.expectedFailure
def test_no_key_function(self):
words = ["apple", "animal", "apple", "animal", "animal"]
word_groups = {
"apple": ["apple", "apple"],
"animal": ["animal", "animal", "animal"],
}
output = group_by(words)
self.assertEqual(output, word_groups)
if __name__ == "__main__":
unittest.main(argv=['ignore-first-argument'], exit=False)
In [28]:
from itertools import groupby
In [38]:
def group_by(iterable, key_func=lambda x: x):
group_by_it = groupby(iterable, key_func)
for key, group in group_by_it:
print (key, list(group))
In [39]:
from operator import itemgetter
import unittest
class GroupByTests(unittest.TestCase):
"""Tests for group_by."""
def test_test_tuples_of_strings(self):
animals = [
('agatha', 'dog'),
('kurt', 'cat'),
('margaret', 'mouse'),
('cory', 'cat'),
('mary', 'mouse'),
]
animals_by_type = {
'mouse': [('margaret', 'mouse'), ('mary', 'mouse')],
'dog': [('agatha', 'dog')],
'cat': [('kurt', 'cat'), ('cory', 'cat')],
}
output = group_by(animals, key_func=itemgetter(1))
self.assertEqual(output, animals_by_type)
def test_strings(self):
words = ["Apple", "animal", "apple", "ANIMAL", "animal"]
word_groups = {
"apple": ["Apple", "apple"],
"animal": ["animal", "ANIMAL", "animal"],
}
output = group_by(words, key_func=str.lower)
self.assertEqual(output, word_groups)
# To test the Bonus part of this exercise, comment out the following line
# @unittest.expectedFailure
def test_no_key_function(self):
words = ["apple", "animal", "apple", "animal", "animal"]
word_groups = {
"apple": ["apple", "apple"],
"animal": ["animal", "animal", "animal"],
}
output = group_by(words)
self.assertEqual(output, word_groups)
if __name__ == "__main__":
unittest.main(argv=['ignore-first-argument'], exit=False)
In [ ]: