-2

I'm trying to sort a dictionary that contains binary strings but it doesn't seem to sort properly. The code I used is below:

dict1 = {"5": "101", "1": "001", "17": "10001", "3" : "11"}
print("Unsorted dict:",dict1)
sorted_tuples = sorted(dict1.items(), key=lambda item: item[1])
print("Sorted tuples:",sorted_tuples)
sorted_dict = {k: v for k, v in sorted_tuples}
print("Sorted dict:",sorted_dict)

I expected the output to be:

Unsorted dict: {'5': '101', '1': '001', '17': '10001', '3': '11'}
Sorted tuples: [('3', '11'), ('1', '001'), ('5', '101'), ('17', '10001')]
Sorted dict: {'3': '11', '1': '001', '5': '101', '17': '10001'}

The reason I thought 11 would come before 001 is that 11 is two charcters and 001 is three. This, I assumed, would continue and a five character string would be sorted after a two character string.

However, the output I do get is:

Unsorted dict: {'5': '101', '1': '001', '17': '10001', '3': '11'}
Sorted tuples: [('1', '001'), ('17', '10001'), ('5', '101'), ('3', '11')]
Sorted dict: {'1': '001', '17': '10001', '5': '101', '3': '11'}

The keys for each value are just symbolic, so it's easier to show. The important parts are the values - they're what I want to sort.

Any suggestions please?

S. Little
  • 17
  • 5
  • 2
    Strings are sorted by default in alphabetical order. If you want to sort by length, use `lambda item: len(item[1])`... – Tomerikoo Jun 26 '22 at 15:09
  • By the way, `sorted_dict` can be as simple as `dict(sorted_tuples)`. But anyway dicts are not ordered structures by nature so there is generally not much reason to sort them – Tomerikoo Jun 26 '22 at 15:14
  • Well, `dict`s are sorted these days and there are real world use-cases that made this useful. – MisterMiyagi Jun 26 '22 at 15:16

1 Answers1

0

TRy this.

dict1 = {"5": "101", "1": "001", "17": "10001", "3" : "11"}
print("Unsorted dict:",dict1)
sorted_tuples = sorted(dict1.items(), key=lambda item: (len(item[1]),int(item[1]))) 
# you can also change int(item[1]) to int(item[0]) or item[1](for binary string as @Tomerikoo say.)
print("Sorted tuples:",sorted_tuples)
sorted_dict = {k: v for k, v in sorted_tuples}
print("Sorted dict:",sorted_dict)

OUTPUT

Unsorted dict: {'5': '101', '1': '001', '17': '10001', '3': '11'}
Sorted tuples: [('3', '11'), ('1', '001'), ('5', '101'), ('17', '10001')]
Sorted dict: {'3': '11', '1': '001', '5': '101', '17': '10001'}

Explaination.

  1. As you say 11 would come before 001 is that 11 is two charcters and 001 is three. Here you need to sort elements by length using len(item[1]).
codester_09
  • 5,622
  • 2
  • 5
  • 27
  • 3
    With binary strings, the `int` conversion is not really necessary (alphabetical order will represent the values' order) – Tomerikoo Jun 26 '22 at 15:16
  • @Tomerikoo Thanks for the information, But What if it is a simple string containing integers? – codester_09 Jun 26 '22 at 15:18
  • @Tomerikoo BUt anyway I will comment this in my code. – codester_09 Jun 26 '22 at 15:19
  • 1
    Then indeed `'9'` will be treated as greater than `'117'`, but the question is specifically about binary strings... This is why I opened my comment with *"with binary strings"* – Tomerikoo Jun 26 '22 at 15:19
  • 1
    Simply dumping a solution without explanation generally isn't all that useful, especially if it has already been repeated often. Please consider to at least [edit] in an outline on the why and how. – MisterMiyagi Jun 26 '22 at 15:20
  • @MisterMiyagi Ok I will edit it with the explanation. – codester_09 Jun 26 '22 at 15:21
  • @Tomerikoo I agree that the `int` conversion is not necessary here. This isn't related to the strings being binary or not. For instance, `'11'` comes after `'101'` in lexicographical order. However, the reason we don't need to convert to `int` here is because we already use `len(item[1])` as the first sorting criterion. So, lexicographical order works, no matter whether the strings are binary or not. – Stef Jun 26 '22 at 19:04
  • @Stef You are completely right. I forgot to mention that this is true under the assumption that the lengths are the same. But I didn't realize that this makes it true for any number not just binary strings. The example I gave in the comment above only happens because of the different of sizes – Tomerikoo Jun 27 '22 at 09:18