19790


string to integerという問題で、

[code]

    class Solution(object):
        def myAtoi(self, str):
            """
            :type str: str
            :rtype: int
            """
            if (str.isnumeric) and str!="":
                return int(str)
            else:
                return 0
    
[/code]

と書いたが、試しにinputで"++"を入力すると、

Line 8: ValueError: invalid literal for int() with base 10: '++'  
が出て、つまり、"+"はisnumericはTrueと判断されている。

isnumericについて検索しましたが、数字だとTrueと書いていました。  
しかし計算に関連する符号、たとえば+,-,%,/もnumericに含むのでしょうか？  
それともこのコードの他の部分が間違っているのでしょうか？  
教えていただけないでしょうか？よろしくお願いします。


CC BY-SA 3.0
2015-12-08T16:19:03.117
19770
2018-09-19T15:27:42.483
2015-12-08T16:38:25.943
13580
13580
question
python
isnumeric() について


function reference != function call

`foo.isnumeric` -> 関数参照  
`foo.isnumeric()` -> 関数呼出し

[code]

    >>> '23'.isnumeric
    <built-in method isnumeric of str object at 0x7feb87baa880>
    >>> '23'.isnumeric()
    True
    
[/code]

`Solution.myAtoi()`はただ`a_to_i()`になります*:

[code]

    >>> def a_to_i(s):
    ...     if s.isnumeric():
    ...         return int(s)
    ...     else:
    ...         return 0
    ... 
    >>> a_to_i('234453')
    234453
    >>> a_to_i('v%87eb8b')
    0
    >>> a_to_i('')
    0
    >>> a_to_i('27.3')
    0
    >>> # あれっ！？
    
[/code]

float型も受け入れる方は:

[code]

    >>> def a_to_n(s):
    ...     if s.isnumeric():
    ...         return int(s)
    ...     else:
    ...         try:
    ...             return float(s)
    ...         except ValueError:
    ...             return 0
    ... 
    >>> a_to_n('3243.245')
    3243.245
    >>> a_to_n('3243.2452.24523')
    0
    >>> a_to_n('Frank')
    0
    >>> a_to_n('25')
    25
    
[/code]

[string].isnumeric()の出力:

[code]

    >>> ''.isnumeric()
    False
    >>> '254231'.isnumeric()
    True
    >>> '24.143'.isnumeric()
    False
    >>> # \(O.o)/ 危ないそれ！
    ...
    >>> for x in range(32, 126):     
    ...     z = chr(x)               
    ...     print(z, z.isnumeric())  
    ... 
      False
    ! False
    " False
    # False
    $ False
    % False
    & False
    ' False
    ( False
    ) False
    * False
    + False
    , False
    - False
    . False
    / False
    0 True
    1 True
    2 True
    3 True
    4 True
    5 True
    6 True
    7 True
    8 True
    9 True
    : False
    ; False
    < False
    = False
    > False
    ? False
    @ False
    A False
    B False
    C False
    D False
    E False
    F False
    G False
    H False
    I False
    J False
    K False
    L False
    M False
    N False
    O False
    P False
    Q False
    R False
    S False
    T False
    U False
    V False
    W False
    X False
    Y False
    Z False
    [ False
    \ False
    ] False
    ^ False
    _ False
    ` False
    a False
    b False
    c False
    d False
    e False
    f False
    g False
    h False
    i False
    j False
    k False
    l False
    m False
    n False
    o False
    p False
    q False
    r False
    s False
    t False
    u False
    v False
    w False
    x False
    y False
    z False
    { False
    | False
    } False
    
[/code]

（* Python != Java.
あるclassとそのclassのinstanceとは違いがなければclassじゃなくてただのfunctionを作った方が良いです。selfを使わないmethodはJavaの"static
method"か"class method"と同じですが、Pythonではclass methodの方はあんまり使いません。なぜならpython
moduleは陰のclassなので、class methodはinner class methodになります。）


CC BY-SA 3.0
2015-12-09T05:04:00.747
19790
2015-12-09T05:04:00.747
2371
19770
answer


コメントにある通りメソッド呼び出しにしないといけないので、`str.isnumeric()` とカッコを補うべきです。

それとは別の話として、`isnumeric()` メソッドは予想外の文字列に対して True を返しうるので注意が必要です。たとえば：

[code]

    >>> "123".isnumeric()  # これは普通
    True
    >>> "１２３".isnumeric()  # 全角数字
    True
    >>> "一万二千三十四".isnumeric()  # 漢数字
    True
    >>> "1¾".isnumeric()  # 分数
    True
    >>> "Ⅲ".isnumeric()  # ローマ数字
    True
    
[/code]

なぜなら Unicode
で[数字扱い](https://en.wikipedia.org/wiki/Numerals_in_Unicode)されている文字たちから成る文字列なら、`isnumeric()`
は True を返してしまうからです。以下、[`isnumeric()`
のドキュメント](https://docs.python.org/ja/3/library/stdtypes.html#str.isnumeric)から引用します。

> 文字列中の全ての文字が数を表す文字で、かつ 1 文字以上あるなら真を、そうでなければ偽を返します。数を表す文字は、数字と、Unicode
> の数値プロパティを持つ全ての文字を含みます。たとえば U+2155 (VULGAR FRACTION ONE
> FIFTH)。正式には、数を表す文字は、プロパティ値 Numeric_Type=Digit、 Numeric_Type=Decimal または
> Numeric_Type=Numeric を持つものです。

上に挙げた例の中には当然のように、`isnumeric()` が True だが `int()` が失敗するものが含まれます。したがって `int()`
が成功するかどうかの条件分岐に `isnumeric()` を使うべきではありません。

**解決策** ：「`int()`
が失敗したかどうか」で判別したいだけなら、[`int()`](https://docs.python.org/ja/3/library/functions.html#int)
が送出する ValueError を補足して失敗判定すると良いでしょう。

[code]

    >>> # 実装例
    ... def myAtoi(s):
    ...     try:
    ...         return int(s)
    ...     except ValueError:
    ...         return 0  # ここにお好みのエラー処理を書く
    ...
    >>> # 動作例
    ... myAtoi("123")
    123
    >>> myAtoi("-123")
    -123
    >>> myAtoi("")
    0
    >>> myAtoi("1.23")
    0
    >>> myAtoi("１２３")
    123
    >>> myAtoi("一万二千三十四")
    0
    >>> myAtoi("   123   ")  # 前後に空白が入っていても良い
    123
    >>> myAtoi("0010")  # Python の整数リテラルとしては 0010 は違法
    10
    
[/code]

判定をもっと厳しく、たとえば「半角数字とプラス・マイナスだけ受け付けたい」という風にするなら、それ専用のバリデーション処理を書くことになります。


CC BY-SA 4.0
2018-09-19T15:19:11.097
48566
2018-09-19T15:27:42.483
2018-09-19T15:27:42.483
19110
19110
19770
answer