views:

98

answers:

2
['7', 'Google', '100T', 'Chrome', '10', 'Python']

I'd like the result to be all numbers at the end and the rest sorted. The numbers need not be sorted.

Chrome
Google
Python
100T
7
10

It's slightly more complicated though, because I sort a dictionary by value.

def sortname(k): return get[k]['NAME']
sortedbyname = sorted(get,key=sortname)

I only added 100T after both answers were posted already, but the accepted answer still works with a slight modification I posted in a comment. To clarify, a name matching ^[^0-9] should be sorted.

+3  A: 

I've been struggling to get a dictionary version working, so here's the array version for you to extrapolate from:

def sortkey(x):
    try:
        return (1, int(x))
    except:
        return (0, x)

sorted(get, key=sortkey)

The basic principle is to create a tuple who's first element has the effect of grouping all strings together then all ints. Unfortunately, there's no elegant way to confirm whether a string happens to be an int without using exceptions, which doesn't go so well inside a lambda. My original solution used a regex, but since moving from a lambda to a stand-alone function, I figured I might as well go for the simple option.

Marcelo Cantos
+1 nifty solution.
delnan
wouldn't this sort the numbers as well?
Lie Ryan
What's wrong with the str.isdigit() function? http://docs.python.org/library/stdtypes.html#str.isdigit
Fara
the numbers "need not be sorted", but supposedly they do not have to maintain their original order, either
Thilo
@Fara: int() would ignore extra spaces, isdigit() don't; it really depends on the OP, whether his input are strict or not.
Lie Ryan
@Lie: The question doesn't stipulate that they *mustn't* be sorted, merely that they *needn't* be sorted.
Marcelo Cantos
@Fara: `str.isdigit()` doesn't handle negative numbers.
Marcelo Cantos
I tried your first solution, and it seems to work. I have removed [-+]? from the regex and int() around the x though, because the numbers are not signed.
pdknsk
@pdknsk: I have changed my solution. The new version, which is more robust, requires the `int()`.
Marcelo Cantos
I forgot to mention a detail, sorry. I added another string to the list to clarify. Based on that the second solution doesn't work. I could use [:1] on the name, but then the list would only be sorted by first character.
pdknsk
In that case, a regex solution is best.
Marcelo Cantos
Or wait, it works. I just use int(x[:1]) instead of [:1] on the dictionary value.
pdknsk
That's clever. It's one of those dammit-why-didn't-I-think-of-that ideas.
Marcelo Cantos
-1 Except that your solution doesn't work with the example proposed by the OP. You are still sorting `100T` as first element, because of course that's not an integer, but the OP puts it with numbers, after alphabetic strings.
Giulio Piancastelli
@Marcelo, sorry, I didn't understand that the example was edited/added later. I'd undo the down-vote if it was possible (now locked unless the answer is modified).
Giulio Piancastelli
Done my part, sorry again.
Giulio Piancastelli
@Guilio: It's cool, really. Given your noob rep, I think I was bit harsh, anyway, so my apologies too. Feel free to delete your comment trail.
Marcelo Cantos
+1  A: 
>>> l = ['7', 'Google', 'Chrome', '10', 'Python']
>>> sorted(l, key=lambda s: (s.isdigit(), s))
['Chrome', 'Google', 'Python', '10', '7']

Python's sort is stable, so you could also use multiple successive sorts:

>>> m = sorted(l)
>>> m.sort(key=str.isdigit)
>>> m
['Chrome', 'Google', 'Python', '10', '7']
adw
-1 This solution wouldn't work with the example proposed by the OP. `100T` is not composed by digits only, but apparently needs not to be sorted (as well as pure numbers).
Giulio Piancastelli
@Guilio: It's not very nice to down-vote someone because their answer doesn't cover an amended question.
Thilo
@Thilo, sorry, I didn't understand the example was edited/added later. I'd undo the down-vote if it was possible (now locked unless the answer is modified).
Giulio Piancastelli