简体   繁体   中英

How to sort a list using a key in python

I have a list of words:

words = ['miel', 'extraterrestre', 'al', 'automovil', 'auto', 'revestir']

I want to sort this list using custom alphabet (it contains 26 letters of the alphabet but ordered in a different way) :

g = 'zyxwvutsrqponmlkjihgfedcba'

Expected result:

['revestir', 'miel', 'extraterrestre', 'auto', 'automovil', 'al']

If speed is important and your list of words is even moderately long, you are probably better off making a lookup rather than searching for the index of each character for each word.

You can use the string function translate() and maketrans() to create a fast way of converting the input strings to a translation for sorting.

For example:

# make translation table 
trans = str.maketrans(g, "".join(sorted(g))) 

# translate words works like:
"revestir".translate(trans)   # 'ivevhgri'

# sort with it:
sorted(l, key=lambda word: word.translate(trans))

# ['revestir', 'miel', 'extraterrestre', 'auto', 'automovil', 'al']

This also has the benefit of being resilient to errors if there are characters in your strings that are not in your alphabet, which index() will choke on. They just get passed through, like:

"reve*stir".translate(trans)
# 'ivev*hgri'

You can use sorted() and pass as a key lambda function which converts your string into a list of indexes of each char of this string in your custom alphabet:

words = ['miel', 'extraterrestre', 'al', 'automovil', 'auto', 'revestir']
g = 'zyxwvutsrqponmlkjihgfedcba'
sorted_words = sorted(words, key=lambda w: [g.index(c) for c in w])

PS This is simplest but definitely not fastest solution, so if your input list is quite big you should consider using solutions from other answers .

The more efficient solution, instead of indexing for every letter would be to build a dictionary beforehand and use the get function which is O(1) for every letter in the word.

pos_map = {}
for idx, letter in enumerate(g):
    pos_map[letter] = idx

def key(item):
    return [pos_map.get(c) for c in item]

sorted(words, key=key)
['revestir', 'miel', 'extraterrestre', 'auto', 'automovil', 'al']
g = 'zyxwvutsrqponmlkjihgfedcba'
order={g[i]:i for i in range(len(g))}
sorted(words, key= lambda word:tuple([order[w] for w in word ]))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM