List sorting in python

My goal is to sort the list of strings in which words should be sorted alphabetically. With the exception of words starting with "s", it should be at the top of the list (they should also be sorted), followed by other words.

The following function does this for me.

def mysort(words): mylist1 = sorted([i for i in words if i[:1] == "s"]) mylist2 = sorted([i for i in words if i[:1] != "s"]) list = mylist1 + mylist2 return list 

I'm just looking for alternative approaches to this, or if anyone can find any problems with the above code.

+4
source share
4 answers

You can do this on one line, for example

 sorted(words, key=lambda x: 'a'+x if x[:1] == 's' else 'b'+x) 

or alternatively:

 sorted(words, key=lambda x: 'a'+x if x.startswith('s') else 'b'+x) 

(More readable.)

sorted () takes the key argument "key", which is used to "translate" the values ​​into a list before performing comparisons.

For instance:

 sorted(words, key=str.lower) # Will do a sort that ignores the case, since instead of checking # 'A' vs. 'b' it will check str.lower('A') vs. str.lower('b') sorted(intlist, key=abs) # Will sort a list of integers by magnitude, regardless of whether they're # negative or positive. >>> sorted([-5,2,1,-8], key=abs) [1, 2, -5, -8] 

The trick I used to translate strings, for example, when sorting:

"hello" => "bhello"
"steve" => "asteve"

And so "steve" comes earlier "hello"

+8
source

1. You can use generator expression inside sorted .

2. You can use str.startswith .

3. Do not use list as a variable name.

4. Use key=str.lower in the sort.

 mylist1 = sorted((i for i in words if i.startswith(("s","S"))),key=str.lower) mylist2 = sorted((i for i in words if not i.startswith(("s","S"))),key=str.lower) return mylist1 + mylist2 

why str.lower ?

 >>> "abc" > "BCD" True >>> "abc" > "BCD".lower() #fair comparison False 
+5
source
 >>> l = ['z', 'a', 'b', 's', 'sa', 'sb', '', 'sz'] >>> sorted(l, key=lambda x:(x[0].replace('s','\x01').replace('S','\x01') if x else '') + x[1:]) ['', 's', 'sa', 'sb', 'sz', 'a', 'b', 'z'] 

This key function replaces for sorting every value that starts with S or S with \x01 , which is sorted before everything else.

+1
source

One of the Integer strings answers I like to use a tuple a little better, because it is cleaner and also more general (works for arbitrary elements, not just strings):

 sorted(key=lambda x : ((1 if x[:1] in ("S", "s") else 2), x)) 

Explanation:

The key parameter allows you to sort the array based on f(item) values ​​instead of item values, where f is an arbitration function.

In this case, the function is anonymous (lambda) and returns a tuple where the first element is the "group" in which you want your element to end (for example, 1 if the line starts with "s" and 2 otherwise).

Using a tuple works because comparing tuples is lexicographically by element, and therefore, when sorting, the group code will weigh more than the element.

+1
source

Source: https://habr.com/ru/post/1491056/


All Articles