3

My program reads in the number parsed from the file name. I want it to be ordered exactly how it is, but, in this example, list as 500, 4000, 7000. How should my naming convention look to achieve this? That is, when I have incrementing numbers, it lists it from smallest to highest.

What I really want is for it to sort by rank, (which here starts at zero), then sorts it by the incrementing numbers.. 500, 5000, 7000.

enter image description here

DESIRED OUTPUT

LOG-rank-0-die-10-delay-500.txt
LOG-rank-0-die-10-delay-4000.txt
LOG-rank-0-die-10-delay-7000.txt
LOG-rank-1-die-10-delay-500.txt
LOG-rank-1-die-10-delay-4000.txt
LOG-rank-1-die-10-delay-7000.txt
LOG-rank-2-die-10-delay-500.txt
LOG-rank-2-die-10-delay-4000.txt
LOG-rank-2-die-10-delay-7000.txt

Relevant Code

for filenamelogs in sorted(os.listdir(log_directory)):
            for each_line in filenamelogs:
                   #various file parsing activity

I'm appending the data file-by-file to various arrays. Unfortunately, this is terrible to me if I can't sort the file reads in the order requested. Maybe my question is veered toward developing a custom method to read in files under the sorting constraints I provide.

Ryan
  • 354
  • 3
  • 18
  • if your numbers can't go over 9999, you could use 0500 instead of 500 – Dleep Jul 07 '15 at 22:10
  • They can exceed that number. This number represent microseconds and can go up to 10 hours. – Ryan Jul 07 '15 at 22:11
  • If your program is reading the strings, it can parse them however it likes. Your question makes very little sense to me. Are you asking about sorting the output of `ls`? – William Pursell Jul 07 '15 at 22:13
  • 2
    Unclear. What is this display you are showing ? It doesnt look like `ls -l` so it's the output of your program ? If yes, I assume python (tag), but then, can you show some related code ? Please clarify question and use case. – kebs Jul 07 '15 at 22:14
  • I'm starting to realize this isn't really coded up in my program as I intended, but it reads in each file, file-by-file. However, if I could get it to read in the files in this type of order, I would be able to have my sorting done for me. I'm not sure how I get the program to read in under this type of sorting requirement. – Ryan Jul 07 '15 at 22:15
  • @kebs The output image is the result of using tree and yes it is the same as ls -1 – Ryan Jul 07 '15 at 22:15
  • possible duplicate of [Does Python have a built in function for string natural sort?](http://stackoverflow.com/questions/4836710/does-python-have-a-built-in-function-for-string-natural-sort) – TigerhawkT3 Jul 07 '15 at 22:29

1 Answers1

5

From a comment on a blog linked in a blog:

>>> import re
>>> def sort_nicely(l):
...     """
...     Sort the given list in the way that humans expect. Modifies the original list.
...     """
...     convert = lambda text: int(text) if text.isdigit() else text
...     alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)]
...     l.sort(key=alphanum_key)
...
>>> mylist = ['LOG-rank-0-die-10-delay-500.txt',
... 'LOG-rank-0-die-10-delay-4000.txt',
... 'LOG-rank-0-die-10-delay-7000.txt',
... 'LOG-rank-1-die-10-delay-500.txt',
... 'LOG-rank-1-die-10-delay-4000.txt',
... 'LOG-rank-1-die-10-delay-7000.txt',
... 'LOG-rank-2-die-10-delay-500.txt',
... 'LOG-rank-2-die-10-delay-4000.txt',
... 'LOG-rank-2-die-10-delay-7000.txt']
>>> sort_nicely(mylist)
>>> print(*mylist, sep='\n')
LOG-rank-0-die-10-delay-500.txt
LOG-rank-0-die-10-delay-4000.txt
LOG-rank-0-die-10-delay-7000.txt
LOG-rank-1-die-10-delay-500.txt
LOG-rank-1-die-10-delay-4000.txt
LOG-rank-1-die-10-delay-7000.txt
LOG-rank-2-die-10-delay-500.txt
LOG-rank-2-die-10-delay-4000.txt
LOG-rank-2-die-10-delay-7000.txt

To return a new, sorted list instead of modifying the original one in place:

>>> def sort_nicely(l):
...     """
...     Sort the given list in the way that humans expect. Returns a new list.
...     """
...     convert = lambda text: int(text) if text.isdigit() else text
...     alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)]
...     return sorted(l, key=alphanum_key)
...
>>> newlist = sort_nicely(mylist)
>>> print(*newlist, sep='\n')
TigerhawkT3
  • 48,464
  • 6
  • 60
  • 97
  • You have no idea the appreciation I have to this comment right now. I've spent a week on this program and this is my last little bug ruining me. Will implement now and see the results. – Ryan Jul 07 '15 at 22:25
  • What should I return from the sort_nicely function to output the sorted list? – Ryan Jul 07 '15 at 22:31
  • 2
    `list.sort()` modifies the original `list`. If you want it to `return` a new `list`, change that line to `return sorted(l, key=alphanum_key)`. You'll then have to save a reference with `newlist = sort_nicely(mylist)` and print that new `list`. – TigerhawkT3 Jul 07 '15 at 22:34
  • 1
    @TigerhawkT3 that last comment is very useful and relevant. Why not add it to your answer for future readers? – LondonRob Jul 07 '15 at 22:49