View difference between Paste ID: vMf7tNA5 and ZzuNtEyi
SHOW: | | - or go back to the newest paste.
1
# Refer to examples in ReversibleDict.__str__
2
3
class PrintableList(list):
4
    
5
    def __init__(self, list_, separator=', ', separate_last=False):
6
        self.separator = separator
7
        self.separate_last = separate_last
8
        list.__init__(self, list_)
9
    
10
    def __str__(self):
11
        """
12
        Return a valid English string representation.
13
        
14
        Example:
15
        >>> for i in range(5): print(i, PrintableList(range(i)))
16
        ... 
17
        (0, [])
18
        (1, [0])
19
        (2, [0, 1])
20
        (3, [0, 1, 2])
21
        (4, [0, 1, 2, 3])
22
        """
23
        
24
        separator = self.separator
25
        separator_last = separator if self.separate_last else ' '
26
        separator_last = '{0}and '.format(separator_last)
27
        
28
        s = (str(i) for i in self)
29
        s = separator.join(s)
30
        s = separator_last.join(s.rsplit(separator, 1))
31
        
32
        return s
33
    
34
35
class ReversibleDict(dict):
36
    
37
    def reversed(self, sort_values=True):
38
        """
39
        Return a reversed dict, with common values in the original dict
40
        grouped into a list in the returned dict.
41
        
42
        Example:
43
        >>> d = ReversibleDict({'a': 3, 'c': 2, 'b': 2, 'e': 3, 'd': 1, 'f': 2})
44
        >>> d.reversed()
45
        {1: ['d'], 2: ['b', 'c', 'f'], 3: ['a', 'e']}
46
        """
47
        
48
        revdict = {}
49
        for k, v in self.iteritems():
50
            revdict.setdefault(v, []).append(k)
51
        if sort_values:
52
            revdict = dict((k, sorted(v)) for k, v in revdict.items())
53
        return revdict
54
    
55
    def _reversed_tuple_revlensorted(self):
56
        """
57
        Return a tuple created from the reversed dict's items (see the 
58
        `reversed` method), with the items in the tuple being reverse sorted by
59
        the length of the reversed dict's values.
60
        
61
        Example:
62
        >>> d = ReversibleDict({'a': 3, 'c': 2, 'b': 2, 'e': 3, 'd': 1, 'f': 2})
63
        >>> d._reversed_tuple_revlensorted()
64
        ((2, ['b', 'c', 'f']), (3, ['a', 'e']), (1, ['d']))
65
        """
66
        
67
        revitems = self.reversed().items()
68
        sortkey = lambda i: (len(i[1]), i[0])
69
        revtuple = tuple(sorted(revitems, key=sortkey, reverse=True))
70
        return revtuple
71
    
72
    def __str__(self):
73
        """
74
        Return a string representation of the reversed dict's items (see the
75
        `reversed` method), sorted per the `_reversed_tuple_revlensorted` 
76
        method.
77
        
78
        Example
79
        >>> print(ReversibleDict({'a':3, 'c':2, 'b':2, 'e':3, 'd':1, 'f':2}))
80
        b, c and f (2); a and e (3); and d (1)
81
        >>> print(ReversibleDict({'a': 3, 'c': 2}))
82
        a (3) and c (2)
83
        """
84
        revtuple = self._reversed_tuple_revlensorted()
85
        
86
        revstrs = ('{0} ({1})'.format(PrintableList(values), key) 
87
                   for key, values in revtuple)
88
        pl_args = ('; ', True) if (max(len(i[1]) for i in revtuple) > 1) else ()
89
        revstrs = PrintableList(revstrs, *pl_args)
90
        revstr = str(revstrs)
91
        return revstr