web-dev-qa-db-fra.com

Liste de tous les caractères uniques dans une chaîne?

Je veux ajouter des caractères à une chaîne, mais je veux m'assurer que toutes les lettres de la liste finale sont unique .

Exemple: "aaabcabccd""abcd"

Maintenant, bien sûr, j'ai deux solutions en tête. L'une utilise une list qui mappera les caractères avec leurs codes ASCII. Ainsi, chaque fois que je rencontre une lettre, l’index est défini sur True. Ensuite, je vais scanner la liste et ajouter toutes celles qui ont été définies. La complexité temporelle sera de O(n) .

Une autre solution consisterait à utiliser une variable dict et à suivre la même procédure. Après avoir mappé chaque caractère, je ferai l'opération pour chaque clé du dictionnaire. Cela aura aussi un temps linéaire .

Depuis que je suis un débutant en Python, je me demandais ce qui serait plus efficace en termes d'espace. Lequel pourrait être mis en œuvre plus efficacement?

PS: L'ordre estpasimportant lors de la création de la liste.

29
Ali

La solution la plus simple est probablement:

In [10]: ''.join(set('aaabcabccd'))
Out[10]: 'acbd'

Notez que cela ne garantit pas l'ordre dans lequel les lettres apparaissent dans la sortie, même si l'exemple suggère le contraire.

Vous vous référez à la sortie comme une "liste". Si vous voulez vraiment une liste, remplacez ''.join par list:

In [1]: list(set('aaabcabccd'))
Out[1]: ['a', 'c', 'b', 'd']

En ce qui concerne les performances, s’inquiéter à ce stade ressemble à une optimisation prématurée.

67
NPE

Utilisez un OrderedDict . Cela garantira que l'ordre est préservé

>>> ''.join(OrderedDict.fromkeys( "aaabcabccd").keys())
'abcd'

PS: Je viens juste de synchroniser les solutions OrderedDict et Set, et la dernière est plus rapide. Si l’ordre n’a pas d’importance, set devrait être la solution naturelle; si l’ordre est important, c’est ce que vous devriez faire.

>>> from timeit import Timer
>>> t1 = Timer(stmt=stmt1, setup="from __main__ import data, OrderedDict")
>>> t2 = Timer(stmt=stmt2, setup="from __main__ import data")
>>> t1.timeit(number=1000)
1.2893918431815337
>>> t2.timeit(number=1000)
0.0632140599081196
15
Abhijit

Par souci d'exhaustivité, voici une autre recette qui trie les lettres comme un sous-produit de son fonctionnement:

>>> from itertools import groupby
>>> ''.join(k for k, g in groupby(sorted("aaabcabccd")))
'abcd'
2
martineau

si le résultat n'a pas besoin de préserver l'ordre, vous pouvez simplement utiliser un ensemble

>>> ''.join(set( "aaabcabccd"))
'acbd'
>>>
1
gefei

J'ai une idée. Pourquoi ne pas utiliser la constante ascii_lowercase?

Par exemple, exécutez le code suivant:

# string module, contains constant ascii_lowercase which is all the lowercase
# letters of the English alphabet
import string
# Example value of s, a string
s = 'aaabcabccd'
# Result variable to store the resulting string
result = ''
# Goes through each letter in the alphabet and checks how many times it appears.
# If a letter appears at least oce, then it is added to the result variable
for letter in string.ascii_letters:
    if s.count(letter) >= 1:
        result+=letter

# Optional three lines to convert result variable to a list for sorting
# and then back to a string
result = list(result)
result.sort()
result = ''.join(result)

print(result)

Imprimera 'abcd'

Voilà, tous les doublons supprimés et éventuellement triés

0
Brent Pappas