Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting in python, and empty strings

Hi I'm using the sorted() function in Python to order a bi-dimensionnal array (I want to sort columns just like it can be done in a classic spreadsheet).

In the example below I use itemgetter(0) to sort the grid based on first column's contents.

But sorted returns empty strings before non-empty ones.

    >>> import operator
    >>> res = [['charly','male','london'],
    ... ['bob','male','paris'],
    ... ['alice','female','rome'],
    ... ['','unknown','somewhere']]
    >>> sorted(res,key=operator.itemgetter(0))
    [['', 'unknown', 'somewhere'], ['alice', 'female', 'rome'], ['bob', 'male', 'paris'], ['charly', 'male', 'london']]
    >>> 

while I would need it to return this:

[['alice', 'female', 'rome'], ['bob', 'male', 'paris'], ['charly', 'male', 'london'], ['', 'unknown', 'somewhere']]

Is there a simple way to do that ?

like image 494
florian Avatar asked Feb 21 '12 22:02

florian


People also ask

Does sort work on strings Python?

Since strings and tuples are immutable, there is no sort() method that updates the original object.

How do you sort and split a string in Python?

In this program, we store the string to be sorted in my_str . Using the split() method the string is converted into a list of words. The split() method splits the string at whitespaces. The list of words is then sorted using the sort() method, and all the words are displayed.

How do you sort a character in a string in Python?

Sort a Python String with Sorted Python comes with a function, sorted() , built-in. This function takes an iterable item and sorts the elements by a given key. The default value for this key is None , which compares the elements directly. The function returns a list of all the sorted elements.


1 Answers

Use a different key function. One that would work is:

sorted(res, key=lambda x: (x[0] == "", x[0].lower()))

The key is then a tuple with either 0 (False) or 1 (True) in the first position, where True indicates that the first item in the record is blank. The second position has the name field from your original record. Python will then sort first into groups of non-blank and blank names, and then by name within the non-blank name gorup. (Python will also sort by name within the blank name group, but since the name's blank it's not going to do anything.)

I also took the liberty of making the name sorting case-insensitive by converting them all to lower-case in the key.

Just replacing the blank names with "ZZZZZZ" or something "alphabetically high" is tempting, but fails the first time some joker puts their name as "ZZZZZZZZ" for a test. I guess something like '\xff' * 100 could work, but it still feels like a hack (also, potential Unicode pitfalls).

like image 95
kindall Avatar answered Sep 20 '22 15:09

kindall