0

I have a JSON file that has file names and a description for each as the key value pairs. However using OrderedDict when I try to sort the file it results in the order 0.jpg 1.jpg 10.jpg 11 ..... 2 20 and so on.

op={int(k) : v for k, v in output.items()}

I tried doing this but it returns a ValueError. The error is as follows

ValueError: invalid literal for int() with base 10: '1520.png'

Abrar Hasin
  • 41
  • 2
  • 9
  • you try to convert `str` to `int` in your case you do `int('1520.png')` – Druta Ruslan Jul 06 '18 at 13:05
  • Seems like you want [Natural sort](https://stackoverflow.com/questions/4836710/does-python-have-a-built-in-function-for-string-natural-sort). – figbeam Jul 06 '18 at 13:07

2 Answers2

2
OrderedDict(sorted(output.items(), key=lambda item: int(item[0].split('.')[0])))

Example

output = {f'{i}.jpg': None for i in reversed(range(21))}

od = OrderedDict(sorted(output.items(), key=lambda item: int(item[0].split('.')[0])))

Output:

OrderedDict([('0.jpg', None),
             ('1.jpg', None),
             ('2.jpg', None),
             ('3.jpg', None),
             ('4.jpg', None),
             ('5.jpg', None),
             ('6.jpg', None),
             ('7.jpg', None),
             ('8.jpg', None),
             ('9.jpg', None),
             ('10.jpg', None),
             ('11.jpg', None),
             ('12.jpg', None),
             ('13.jpg', None),
             ('14.jpg', None),
             ('15.jpg', None),
             ('16.jpg', None),
             ('17.jpg', None),
             ('18.jpg', None),
             ('19.jpg', None),
             ('20.jpg', None)])
FHTMitchell
  • 11,793
  • 2
  • 35
  • 47
1

You're calling the int() function on a string that's not entirely made up of digits. The dictionary comprehension you've built is going loops through each key/value pair in the original dict output and tries to cast each key to an integer.

In your example the keys are filenames like "0.png", "1.jpg", "10.png", etc. and a string like '10.png' can't be turned in to an integer. That's why you're getting the ValueError.

Ordering dictionaries in Python is a little tricky because we think everything should be based on a key's value when in fact Python orders dictionary keys based on their hash value.

As for using an OrderedDict, that container only remembers the order in which the keys were inserted. It sounds like it would give you some sorting capability, but it can only guarantee that the order in which you loop through keys is the same as the order you put them in the dictionary.

This should help you out though:

od = OrderedDict()
for key in sorted(output):
    od[key] = output[key]

This will put all the keys of the original dict output in a list, sort it, and then stick each one in sorted order in the OrderedDict with the correct value.

AvlWx
  • 291
  • 3
  • 9