Skip to content

Commit 886f45c

Browse files
committed
-
1 parent 2b8d346 commit 886f45c

File tree

5 files changed

+59
-13
lines changed

5 files changed

+59
-13
lines changed

python_toolbox/comparison_tools.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,15 @@ def total_ordering(cls):
5454
setattr(cls, opname, opfunc)
5555
return cls
5656

57+
58+
def process_key_function_or_attribute_name(key_function_or_attribute_name):
59+
if key_function_or_attribute_name is None:
60+
return None
61+
elif callable(key_function_or_attribute_name):
62+
return key_function_or_attribute_name
63+
else:
64+
assert isinstance(key_function_or_attribute_name, basestring)
65+
return lambda key: getattr(key, key_function_or_attribute_name)
66+
67+
68+

python_toolbox/dict_tools.py

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
'''Defines several functions that may be useful when working with dicts.'''
55

66
from python_toolbox import cute_iter_tools
7+
from python_toolbox import comparison_tools
78

89

910
def filter_items(d, condition, force_dict_type=None):
@@ -60,7 +61,7 @@ def show(thing, indent=0):
6061
return temp2
6162

6263

63-
def reverse_with_set_values(d):
64+
def reverse_with_set_values(d, sort=False):
6465
'''
6566
Reverse the dict, with the values of the new dict being sets.
6667
@@ -72,6 +73,10 @@ def reverse_with_set_values(d):
7273
Instead of a dict you may also input a tuple in which the first item is an
7374
iterable and the second item is either a key function or an attribute name.
7475
A dict will be constructed from these and used.
76+
77+
If you'd like the result dict to be sorted, pass `sort=True`, and you'll
78+
get a sorted `OrderedDict`. You can also specify the sorting key function
79+
or attribute name as the `sort` argument.
7580
'''
7681
### Pre-processing input: #################################################
7782
# #
@@ -81,13 +86,9 @@ def reverse_with_set_values(d):
8186
assert cute_iter_tools.is_iterable(d) and len(d) == 2
8287
iterable, key_function_or_attribute_name = d
8388
assert cute_iter_tools.is_iterable(iterable)
84-
if callable(key_function_or_attribute_name):
85-
key_function = key_function_or_attribute_name
86-
else:
87-
assert isinstance(key_function_or_attribute_name, basestring)
88-
key_function = \
89-
lambda key: getattr(key, key_function_or_attribute_name)
90-
89+
key_function = comparison_tools.process_key_function_or_attribute_name(
90+
key_function_or_attribute_name
91+
)
9192
fixed_dict = dict((key, key_function(key)) for key in iterable)
9293
# #
9394
### Finished pre-processing input. ########################################
@@ -102,7 +103,19 @@ def reverse_with_set_values(d):
102103
for key, value in new_dict.copy().iteritems():
103104
new_dict[key] = set(value)
104105

105-
return new_dict
106+
if sort:
107+
from python_toolbox import nifty_collections
108+
ordered_dict = nifty_collections.OrderedDict(new_dict)
109+
if callable(sort) or isinstance(sort, basestring):
110+
key_function = comparison_tools. \
111+
process_key_function_or_attribute_name(sort)
112+
else:
113+
assert sort is True
114+
key_function = None
115+
ordered_dict.sort(key_function)
116+
return ordered_dict
117+
else:
118+
return new_dict
106119

107120

108121
def devour_items(d):

python_toolbox/nifty_collections/ordered_dict.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77
See its documentation for more information.
88
'''
99

10-
1110
from UserDict import DictMixin
1211

12+
from python_toolbox import comparison_tools
13+
1314

1415
class OrderedDict(dict, DictMixin):
1516
'''Dict that maintains order of items.'''
@@ -168,9 +169,11 @@ def sort(self, key=None):
168169
The optional `key` argument, (not to be confused with the dictionary
169170
keys,) will be passed to the `sorted` function as a key function.
170171
'''
171-
sorted_keys = sorted(self.keys(), key=key)
172-
for key in sorted_keys[1:]:
173-
self.move_to_end(key)
172+
key_function = \
173+
comparison_tools.process_key_function_or_attribute_name(key)
174+
sorted_keys = sorted(self.keys(), key=key_function)
175+
for key_ in sorted_keys[1:]:
176+
self.move_to_end(key_)
174177

175178

176179
def index(self, key):

test_python_toolbox/test_dict_tools/test_reverse_with_set_values.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
'''Test package for `dict_tools.reverse_with_set_values`.'''
55

66
from python_toolbox import dict_tools
7+
from python_toolbox import nifty_collections
78

89

910
def test():
@@ -17,4 +18,14 @@ def test_iterable_input():
1718

1819
assert dict_tools.reverse_with_set_values(([1, 2+3j, 4, 5-6j], 'imag')) \
1920
== {0: set([1, 4]), 3: set([2+3j]), -6: set([5-6j])}
21+
22+
23+
def test_ordered_dict_output():
24+
assert dict_tools.reverse_with_set_values({1: 2, 3: 4, 'meow': 2},
25+
sort=True) == \
26+
nifty_collections.OrderedDict([(2, set([1, 'meow'])), (4, set([3]))])
27+
28+
assert dict_tools.reverse_with_set_values({1: 2, 3: 4, 'meow': 2},
29+
sort=lambda x: -x) == \
30+
nifty_collections.OrderedDict([(4, set([3])), (2, set([1, 'meow']))])
2031

test_python_toolbox/test_nifty_collections/test_ordered_dict/test.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ def test_sort():
3737
assert ordered_dict == ordered_dict_copy
3838

3939

40+
second_ordered_dict = OrderedDict(((1+2j, 'b'), (2+3j, 'c'), (3+1j, 'a')))
41+
second_ordered_dict.sort('imag')
42+
assert second_ordered_dict == \
43+
OrderedDict(((3+1j, 'a'), (1+2j, 'b'), (2+3j, 'c')))
44+
45+
46+
4047
def test_index():
4148
'''Test the `OrderedDict.index` method.'''
4249
ordered_dict = OrderedDict(((1, 'a'), (2, 'b'), (3, 'c')))

0 commit comments

Comments
 (0)