56

文字列に文字を追加したいのですが、最終的なリストのすべての文字が一意であることを確認したいと思います。

例:"aaabcabccd""abcd"

もちろん、私は2つの解決策を考えています。list1つは、文字をASCIIコードにマップするを使用しています。したがって、文字に遭遇するたびに、インデックスがに設定されTrueます。その後、リストをスキャンして、設定されたものをすべて追加します。時間計算量はO(n)になります。

別の解決策は、とを使用しdictて同じ手順に従うことです。すべての文字をマッピングした後、辞書の各キーの操作を実行します。これには、線形の実行時間もあります。

私はPythonの初心者なので、どちらがよりスペース効率が良いのか疑問に思いました。どちらをより効率的に実装できますか?

PS :リストを作成するときの順序は重要ではありません。

4

7 に答える 7

116

最も簡単な解決策はおそらく次のとおりです。

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

これは、例で別の方法が示唆されている場合でも、出力に文字が表示される順序を保証するものではないことに注意してください。

出力を「リスト」と呼びます。リストが本当に必要なものである場合は、次のように置き換え''.joinますlist

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

パフォーマンスに関する限り、この段階でそれを心配することは時期尚早の最適化のように聞こえます。

于 2012-12-16T15:36:04.277 に答える
22

OrderedDictを使用します。これにより、注文が確実に保持されます

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

PS:OrderedDictとSetの両方のソリューションのタイミングを調整しましたが、後者の方が高速です。順序が重要でない場合は、setが自然な解決策である必要があります。順序が重要な場合は、これを行う必要があります。

>>> 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
于 2012-12-16T15:36:38.740 に答える
6

完全を期すために、文字をその動作の副産物として分類する別のレシピを次に示します。

>>> from itertools import groupby
>>> ''.join(k for k, g in groupby(sorted("aaabcabccd")))
'abcd'
于 2012-12-16T16:08:31.743 に答える
4
char_seen = []
for char in string:
    if char not in char_seen:
        char_seen.append(char)
print(''.join(char_seen))

これにより、アルファベットが来る順序が維持されます。

出力は

abcd
于 2019-10-16T06:24:31.127 に答える
3

結果が順序を維持する必要がない場合は、セットを使用するだけです。

>>> ''.join(set( "aaabcabccd"))
'acbd'
>>>
于 2012-12-16T15:36:13.683 に答える
2

考えがある。ascii_lowercase定数を使ってみませんか?

たとえば、次のコードを実行します。

# string module contains the 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 once, 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)

印刷します'abcd'

さあ、すべての重複を削除し、オプションで並べ替えます

于 2017-10-26T14:55:26.423 に答える
2

一意の文字をリストに保存する

方法1:

uniue_char = list(set('aaabcabccd'))
#['a', 'b', 'c', 'd']

方法2:ループによる(複雑)

uniue_char = []
for c in 'aaabcabccd':
    if not c in uniue_char:
        uniue_char.append(c)
print(uniue_char)
#['a', 'b', 'c', 'd']
于 2019-06-03T11:36:16.080 に答える