Como classificar uma lista de strings?

417

Qual é a melhor maneira de criar uma lista ordenada alfabeticamente em Python?

Skolima
fonte
1
Use localee seus métodos de agrupamento de strings para classificar naturalmente de acordo com a localidade atual.
u0b34a0f6ae 8/09/09

Respostas:

519

Resposta básica:

mylist = ["b", "C", "A"]
mylist.sort()

Isso modifica sua lista original (ou seja, classifica no local). Para obter uma cópia classificada da lista, sem alterar o original, use a sorted()função:

for x in sorted(mylist):
    print x

No entanto, os exemplos acima são um pouco ingênuos, porque não levam em consideração o código do idioma e executam uma classificação que diferencia maiúsculas de minúsculas. Você pode tirar proveito do parâmetro opcional keypara especificar a ordem de classificação personalizada (a alternativa, usando cmp, é uma solução descontinuada, pois precisa ser avaliada várias vezes - keyé calculada apenas uma vez por elemento).

Portanto, para classificar de acordo com a localidade atual, levando em consideração as regras específicas do idioma ( cmp_to_keyé uma função auxiliar do functools):

sorted(mylist, key=cmp_to_key(locale.strcoll))

E, finalmente, se necessário, você pode especificar um código de idioma personalizado para classificação:

import locale
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') # vary depending on your lang/locale
assert sorted((u'Ab', u'ad', u'aa'),
  key=cmp_to_key(locale.strcoll)) == [u'aa', u'Ab', u'ad']

Última observação: você verá exemplos de classificação sem distinção entre maiúsculas e minúsculas que usam o lower()método - esses estão incorretos, porque funcionam apenas para o subconjunto de caracteres ASCII. Esses dois estão errados para qualquer dado que não seja o inglês:

# this is incorrect!
mylist.sort(key=lambda x: x.lower())
# alternative notation, a bit faster, but still wrong
mylist.sort(key=str.lower)
Eli Courtwright
fonte
37
mylist.sort(key=str.lower)é mais rápido.
JFS
1
Bom ponto. Vou deixar meu exemplo atual como está, já que provavelmente é mais fácil para um iniciante ver o que está acontecendo, mas vou manter isso em mente no futuro.
Eli Courtwright 28/10/08
1
Se alguém estiver curioso, o desempenho de list.sort () pode ser encontrado aqui #
Hari Ganesan
1
@BornToCode: 1- Eu sei . Veja a revisão (2008) à qual meu comentário responde (meu comentário é sobre o uso desnecessário de lambda). 2- A classificação de caracteres não ASCII é um grande tópico separado. PyICU poderia ser usado em vez da solução baseada em localidade.
JFS
1
@Dmitry Isso ocorre porque você está imprimindo o valor de retorno da função de classificação chamada [1, 2, 3].sort(). Conforme sort()classifica a lista no local (ou seja, altera a lista diretamente), ela não retorna a lista classificada e, na verdade, não retorna nada; portanto, sua declaração de impressão é impressa None. Se você salvou sua lista em uma variável, digamos x, chamada x.sort(), então print(x), você veria a lista classificada.
bjg222
56

Também vale a pena notar a sorted()função:

for x in sorted(list):
    print x

Isso retorna uma nova versão classificada de uma lista sem alterar a lista original.

Greg Hewgill
fonte
36
list.sort()

É realmente muito simples :)

rix0rrr
fonte
18

A maneira correta de classificar strings é:

import locale
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') # vary depending on your lang/locale
assert sorted((u'Ab', u'ad', u'aa'), cmp=locale.strcoll) == [u'aa', u'Ab', u'ad']

# Without using locale.strcoll you get:
assert sorted((u'Ab', u'ad', u'aa')) == [u'Ab', u'aa', u'ad']

O exemplo anterior mylist.sort(key=lambda x: x.lower())funcionará bem para contextos somente ASCII.

schmichael
fonte
13

Por favor, use a função classificada () no Python3

items = ["love", "like", "play", "cool", "my"]
sorted(items2)
Mahmud Ahsan
fonte
10

Mas como isso lida com regras de classificação específicas do idioma? Ele leva em consideração a localidade?

Não, list.sort()é uma função de classificação genérica. Se você deseja classificar de acordo com as regras Unicode, precisará definir uma função de chave de classificação personalizada. Você pode tentar usar o módulo pyuca , mas não sei o quão completo ele é.

John Millikin
fonte
1

Pergunta antiga, mas se você deseja fazer a classificação com reconhecimento de localidade sem definir, locale.LC_ALL pode fazê-lo usando a biblioteca PyICU, conforme sugerido por esta resposta :

import icu # PyICU

def sorted_strings(strings, locale=None):
    if locale is None:
       return sorted(strings)
    collator = icu.Collator.createInstance(icu.Locale(locale))
    return sorted(strings, key=collator.getSortKey)

Em seguida, ligue com, por exemplo:

new_list = sorted_strings(list_of_strings, "de_DE.utf8")

Isso funcionou para mim sem instalar nenhum local ou alterar outras configurações do sistema.

(Isso já foi sugerido em um comentário acima , mas eu queria dar mais destaque, porque senti falta disso primeiro.)

vlz
fonte
0

Suponha s = "ZWzaAd"

Para classificar a string acima, a solução simples estará abaixo de uma.

print ''.join(sorted(s))
JON
fonte
que não é uma lista de strings você está classificando aqui
MNL
0

Ou talvez:

names = ['Jasmine', 'Alberto', 'Ross', 'dig-dog']
print ("The solution for this is about this names being sorted:",sorted(names, key=lambda name:name.lower()))
Dragos Alexe
fonte
0
l =['abc' , 'cd' , 'xy' , 'ba' , 'dc']
l.sort()
print(l1)

Resultado

['abc', 'ba', 'cd', 'dc', 'xy']

asing177
fonte
0

É simples: https://trinket.io/library/trinkets/5db81676e4

scores = '54 - Alice,35 - Bob,27 - Carol,27 - Chuck,05 - Craig,30 - Dan,27 - Erin,77 - Eve,14 - Fay,20 - Frank,48 - Grace,61 - Heidi,03 - Judy,28 - Mallory,05 - Olivia,44 - Oscar,34 - Peggy,30 - Sybil,82 - Trent,75 - Trudy,92 - Victor,37 - Walter'

scores = scores.split (',') para x no ordenado (scores): print (x)

Hedayatullah Sarwary
fonte