-1
list_dict = [{
'filename': '4008789155603(0).jpg',
'barcode': '4008789155603'
},
{
'filename': '4008789155603(1).jpg',
'barcode': '4008789155603'
},
{
'filename': '4008789155603(10).jpg',
'barcode': '4008789155603'
},
{
'filename': '4008789155603(11).jpg',
'barcode': '4008789155603'
},
{
'filename': '4008789155603(12).jpg',
'barcode': '4008789155603'
},
{
'filename': '4008789155603(13).jpg',
'barcode': '4008789155603'
},
{
'filename': '4008789155603(2).jpg',
'barcode': '4008789155603'
},
{
'filename': '4008789155603(3).jpg',
'barcode': '4008789155603'
},
{
'filename': '4008789155603(4).jpg',
'barcode': '4008789155603'
},
{
'filename': '4008789155603(5).jpg',
'barcode': '4008789155603'
},
{
'filename': '4008789155603(6).jpg',
'barcode': '4008789155603'
},
{
'filename': '4008789155603(7).jpg',
'barcode': '4008789155603'
},
{
'filename': '4008789155603(8).jpg',
'barcode': '4008789155603'
},
{
'filename': '4008789155603(9).jpg',
'barcode': '4008789155603'
}]

when I tried to sort this list of dictionary based on the 'filename' value it does not sort with the appropriate result.

Every time I got- 4008789155603(0).jpg, 4008789155603(1).jpg, 4008789155603(10).jpg, 4008789155603(11).jpg

Output: 4008789155603(0).jpg, 4008789155603(1).jpg, 4008789155603(3).jpg, 4008789155603(4).jpg, ..., 4008789155603(10).jpg, 4008789155603(11).jpg, 4008789155603(12).jpg

Dipen Shah
  • 2,396
  • 2
  • 9
  • 21
  • If you want to sort the list, why are you looping it? Why not just `sort(list_dict, key=lambda d: d['filename'])`? – Tomerikoo May 27 '20 at 10:34
  • 1
    The issue is that the default sorting key for strings does a "naive" sort based on unicode codepoints only, meaning it goes 1, 10, 11, 2, 3, 4, 5, 6, 7, 8, 9. There's apparently a `natsort` library that alleviates this: https://stackoverflow.com/a/18415320/1016216 – L3viathan May 27 '20 at 10:35
  • 1
    @L3viathan you are right about that point, but I don't believe this is the main issue with the question. For starters the output presented here is not the one of the code given, so OP needs to clarify. Second, according to the code, he is looping the list and simply printing the dicts **in order** and not sorting them like he thinks... So again, you are correct with your comment, but the problem here is that they are simply printed by order in the list (and no sorting is done at all...) – Tomerikoo May 27 '20 at 10:41
  • @Tomerikoo Good point. I'll reopen. – L3viathan May 27 '20 at 11:10

1 Answers1

0

Short-Answer:

list_dict = [{ 'filename': '4008789155603(0).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(1).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(10).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(11).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(12).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(13).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(2).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(3).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(4).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(5).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(6).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(7).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(8).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(9).jpg', 'barcode': '4008789155603' }]

sorted(list_dict, key=lambda entry: int(entry.get("filename").replace("(", "").replace(")", "").strip(".jpg")))

For better readability:

#input list
list_dict = [{ 'filename': '4008789155603(0).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(1).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(10).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(11).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(12).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(13).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(2).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(3).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(4).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(5).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(6).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(7).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(8).jpg', 'barcode': '4008789155603' }, { 'filename': '4008789155603(9).jpg', 'barcode': '4008789155603' }]

#sorting lambda function
f_sort = lambda entry : int(entry.get("filename").replace("(", "").replace(")", "").strip(".jpg"))

#output list
list_dict_sorted = sorted(list_dict, key=lambda entry: f_sort(entry))

If you prefer a "normal" function:

def f_sort(entry):
    return int(entry.get("filename").replace("(", "").replace(")", "").strip(".jpg"))

Explaination:

Lists can get sorted with a "key" parameter, which essentially can be anything. Since your filenames are essentially numbers type(int) but formated as strings python also sorts them as strings. To get a numerical sorting we therefore need to transform them first back to numbers. Since we only need those for the sorting we can create a lambda function transforming the filenames before considering them for sorting.

Andreas
  • 8,694
  • 3
  • 14
  • 38