4

私が書こうとしている関数では、ユーザーは「648392」などの一連の数字を入力します。この文字列を ['6', '4', '8', '3', '9', '2'] のようなリストに変換します。

これらの数値を合計できるようにしたかったので、リスト内の数値を文字列ではなく整数に変換していました。これはすべてうまくいきましたが、ユーザーが文字を入力できるようにしたかったので、リストからそれらを削除するだけでした-これが私が立ち往生している場所です. たとえば、ユーザーが「6483A2」と入力したとします。

要素が明らかに最初に整数でなければならないため、要素が数字であるかどうかを isDigit で確認することはできません。また、要素の一部が文字であるため、リスト内の要素を整数に変換することもできません。簡単な解決策があると確信していますが、私はPythonがかなり苦手なので、どんな助けも大歓迎です!

4

7 に答える 7

6

str.translate文字を除外するために使用できます。

>>> from string import letters
>>> strs = "6483A2"
>>> strs.translate(None, letters)
'64832'

文字列をリストに変換する必要はありません。文字列自体を反復処理できます。

str.joinstr.isdigitおよびリスト内包表記の使用:

>>> ''.join([c for c in strs if c.isdigit()])
'64832'

sumまたはこれは、数字の必要に応じて:

sum(int(c) for c in strs if c.isdigit())

タイミング比較:

小さな文字列:

>>> strs = "6483A2"
>>> %timeit sum(int(c) for c in strs.translate(None, letters))
100000 loops, best of 3: 9.19 us per loop
>>> %timeit sum(int(c) for c in strs if c.isdigit())
100000 loops, best of 3: 10.1 us per loop

大きな文字列:

>>> strs = "6483A2"*1000
>>> %timeit sum(int(c) for c in strs.translate(None, letters))
100 loops, best of 3: 5.47 ms per loop
>>> %timeit sum(int(c) for c in strs if c.isdigit())
100 loops, best of 3: 8.54 ms per loop

最悪の場合、すべての文字:

>>> strs = "A"*100
>>> %timeit sum(int(c) for c in strs.translate(None, letters))
100000 loops, best of 3: 2.53 us per loop
>>> %timeit sum(int(c) for c in strs if c.isdigit())
10000 loops, best of 3: 24.8 us per loop
>>> strs = "A"*1000
>>> %timeit sum(int(c) for c in strs.translate(None, letters))
100000 loops, best of 3: 7.34 us per loop
>>> %timeit sum(int(c) for c in strs if c.isdigit())
1000 loops, best of 3: 210 us per loop
于 2013-08-08T00:58:58.567 に答える
3

filter関数または内包表記を使用して、反復可能なもの (文字列を含む) をフィルター処理して除外できます。たとえば、次のいずれかです。

digits = filter(str.isdigit, input_string)
digits = (character for character in input_string if character.isdigit())

... 数字でいっぱいの iterable が得られます。それぞれを数値に変換する場合は、次のいずれかで実行できます。

numbers = map(int, filter(str.isdigit, input_string))
numbers = (int(character) for character in input_string if character.isdigit())

したがって、文字をスキップしてすべての数字の合計を取得するには、それらのいずれかをsum関数に渡すだけです。

total = sum(map(int, filter(str.isdigit, input_string)))
total = sum(int(character) for character in input_string if character.isdigit())

あなたの最後の段落から:

要素が最初に整数でなければならないため、要素が数字であるかどうかを isDigit で確認することはできず、リスト内の要素を整数に変換することもできません。

まず、isdigitではなくisDigitです。2 つ目isdigitは、整数ではなく文字列に対するメソッドであるため、文字列に対して呼び出すことができないと考えるのは誤りです。実際、文字列を整数に変換する前に、文字列に対して呼び出す必要があります。

しかし、これは別のオプションをもたらします。Python では、多くの場合、 Permission よりも許しを求める方が簡単です。各文字を int に変換できるかどうかを調べてから実行する代わりに、単に int に変換してから、起こりうる失敗に対処することができます。例えば:

def get_numbers(input_string):
    for character in input_string:
        try:
            yield int(character)
        except TypeError:
            pass

今、それはただです:

total = sum(get_numbers(input_string))
于 2013-08-08T01:00:33.850 に答える