Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting a dictionary by a split key

Ok, so I have a dictionary that contains positions of characters in a string, however, I've got individual strings inside the dictionary, which makes it look like this:

{
'24-35': 'another word',
'10-16': 'content',
'17': '[',
'22': ']',
'23': '{',
'37': ')',
'0-8': 'beginning',
'36': '}',
'18-21': 'word',
'9': '(',
}

I'm trying to sort this array by the keys, so that it'd look like this

{
'0-8': 'beginning',
'9': '(',
'10-16': 'content',
'17': '[',
'18-21': 'word',
'22': ']',
'23': '{',
'24-35': 'another word',
'36': '}',
'37': ')'
}

The dictionary is built by foreaching through this string:
'beginning(content[word]{another word})', and splitting at the brackets.

I'm trying to sort the dictionary by using @Brian's answer to this question, however, it sorts by the alphabetically (because they've been transformed to strings) at the ranging process (the thing that makes it say '0-8').

My question is:

How can I transform:

class SortedDisplayDict(dict):
   def __str__(self):
       return "{" + ", ".join("%r: %r" % (key, self[key]) for key in sorted(self)) + "}"

and more specifically: the sorted key into int(key.split('-')[0]), but still keep the output with ranges?

like image 821
Quill Avatar asked May 24 '15 03:05

Quill


People also ask

Can you sort a dictionary based on keys?

Dictionaries are made up of key: value pairs. Thus, they can be sorted by the keys or by the values.

Can you sort a Python dictionary by key?

Sort Dictionary by Key in Python Apart from sorting the dictionary using values, we can also sort the dictionary using the keys component. Below are 3 methods to sort the dictionary using keys.

How do you sort by two keys in Python?

How do you sort multiple keys in Python? Use a lambda function with a tuple to sort with two keys Call sorted(iterable, key: NoneType=None) with a collection as iterable . For key , create a lambda function that takes an element as a parameter and returns a 2-tuple of mapped to values.

Can you sort a dictionary by key C#?

You can't sort a Dictionary<TKey, TValue> - it's inherently unordered. (Or rather, the order in which entries are retrieved is implementation-specific.


2 Answers

Use a key function for sorted that casts the value to an int. It'd look like:

sorted(d.items(), key=lambda v: int(v[0].split("-")[0]))

This logic would only be used for sorting; the items that sorted returned would still use range notation.

like image 185
jwilner Avatar answered Oct 23 '22 05:10

jwilner


You can convert the dictionary to a list of tuples (key-value pairs) and then sort them based on the second number in the key if it is hyphenated.

>>> data = {'24-35': 'another word', '10-16': 'content', '17':
...         '[', '22': ']', '23': '{', '37': ')', '0-8': 'beginning', '36': '}',
...         '18-21': 'word', '9': '('}
>>> from pprint import pprint
>>> pprint(sorted(data.items(),
...     key=lambda x: int(x[0].split("-")[1] if "-" in x[0] else x[0])))

[('0-8', 'beginning'),
 ('9', '('),
 ('10-16', 'content'),
 ('17', '['),
 ('18-21', 'word'),
 ('22', ']'),
 ('23', '{'),
 ('24-35', 'another word'),
 ('36', '}'),
 ('37', ')')]

Here, the key part is lambda x: int(x[0].split("-")[1] if "-" in x[0] else x[0]). We check if - is in the x[0], if it is present, then we split based on - and take the element at index 1, basically the number after -. If the key doesn't have - then convert the string as it is to int.


If you want to maintain the order of the items in the dictionary itself, then you can use collections.OrderedDict, like this

>>> from collections import OrderedDict
>>> d = OrderedDict(sorted(data.items(),
...         key=lambda x: int(x[0].split("-")[1] if "-" in x[0] else x[0])))
>>> for key, value in d.items():
...     print(key, value)
...     
... 
0-8 beginning
9 (
10-16 content
17 [
18-21 word
22 ]
23 {
24-35 another word
36 }
37 )
like image 4
thefourtheye Avatar answered Oct 23 '22 06:10

thefourtheye