web-dev-qa-db-ja.com

Python-0.0のステートメントでない場合

if notPython 2.7ステートメントについて質問があります。

私はいくつかのコードを書き、if notステートメントを使用しました。私が書いたコードの一部では、オプションのキーワードが入力されているかどうかを判断するために、if notステートメントを含む関数を参照しています。

0.0がキーワードの値である場合を除いて、正常に機能します。これは、0が「ではない」と見なされるものの1つであるためです。私のコードはおそらく投稿するには長すぎますが、これは類似した(単純化されていますが)例です:

def square(x=None):
    if not x:
        print "you have not entered x"
    else:
        y=x**2
        return y

list=[1, 3, 0 ,9]
output=[]


for item in list:
    y=square(item)
    output.append(y)

print output

しかし、この場合、私は残されました:

you have not entered x
[1, 9, None, 81]    

入手したい場所:

[1, 9, 0, 81]

上記の例では、リスト内包表記を使用できますが、関数を使用して目的の出力を取得したい場合、どうすればよいでしょうか。

私が持っていた1つの考えは:

def square(x=None):
    if not x and not str(x).isdigit():
        print "you have not entered x"
    else:
        y=x**2
        return y

list=[1, 3, 0 ,9]
output=[]


for item in list:
    y=square(item)
    output.append(y)

print output

これは機能しますが、少し不格好な方法のようです。誰かがニースになる別の方法を持っているなら、私は非常に感謝するでしょう。

19
TheBoro

問題

あなたはそれを正しく理解しています。 _not 0_(および_not 0.0_)は、TruePythonを返します。これを確認するために簡単なテストを行うことができます。

_a = not 0
print(a)

Result: True
_

したがって、問題が説明されます。この行:

_if not x:
_

他のものに変更する必要があります。


ソリューション

この問題を解決するために実行できる方法はいくつかあります。 list に、最善の解決策から最後の可能な解決策まで、次のように説明します。


  1. 考えられるすべての有効なケースを処理する

    squareは当然複素数を除いた数値入力を期待し、そうでない場合はreturnエラーになるはずなので、最善の解決策はif not isinstance(x, numbers.Number) or isinstance(x, numbers.Complex):を使用して評価することだと思います。

    _def square(x=None):
        if not isinstance(x, numbers.Number) or isinstance(x, numbers.Complex): # this sums up every number type, with the exclusion of complex number
            print ("you have not entered x")
        else:
            y=x**2
            return y
    
    list=[1, 3, 0 ,9]
    output=[]
    
    for item in list:
        y=square(item)
        output.append(y)
    
    print (output)
    _

    numbers.Number the 抽象クラスであり、引数xが数値であるかどうかを確認します(これを指摘するための Copperfield のクレジット)。

    Python標準ライブラリドキュメント からの抜粋 just 必要なもの-複素数を除いて:

    class numbers.Number

    数値階層のルート。引数xが数値、種類を気にせずであるかどうかを確認したいだけの場合は、isinstance(x、Number)を使用します。

    ただし、入力が複素数になることは望ましくありません。したがって、or isinstance(x, numbers.Complex)を使用して省略してください。

    このようにして、definitionsquare正確に好きなように記述します。この解決策は、包括性のおかげで最良解決策だと思います。


  1. 処理したいデータ型だけを処理するには

    有効な入力データ型のリストがある場合は、処理する特定のデータ型だけを表示することもできます。つまり、指定したデータ型以外のデータ型のケースを処理する必要はありません。例:

    _if not instance(x, int): #just handle int
    if not instance(x, (int, float)): #just handle int and float
    if not instance(x, (numbers.Integral, numbers.Rational)): #just handle integral and rational, not real or complex
    _

    必要に応じて、含めるまたは除外するさまざまなデータ型について、上記の条件を easy に変更/拡張できます。この解決策は、妥当性チェックのカスタマイズのおかげで次善の策だと思います。

    (上記のコードは、 cat で提案されているように、より Pythonical の方法で実行されます)


  1. 不可能なケースを処理しない:ユーザーが not 入力として提示するものを知っている

    2番目のソリューションのように処理したいデータ型ではなく、ユーザーが not 入れたデータ型がわかっている場合は、もっと大まかに考えてください。このような状態チェック:

    _if not isinstance(x, numbers.Number): # this is ok, because the user would not put up complex number
    _

    この解決策は、最も単純で強力なチェックの1つであるという理由で番目に良いだと思います。

    このソリューションの唯一の欠点は、複合型を処理しないことです。したがって、ユーザーが入力として複素数を持たないという事実のためにのみ実装できます。


  1. エラーの原因となる可能性のある既知の入力に対してのみ入力エラーを処理する

    たとえば、xが常にintまたはNoneであり、したがって唯一の入力エラーがNoneであることがわかっている場合は、yが評価されないようにロジックを記述できます only when xNoneは次のようになります:

    _def square(x=None):
        if x is None:
            print ("you have not entered x")
        else:
           y=x**2
           return y
    
    list=[1, 3, 0 ,9]
    output=[]
    
    for item in list:
        y=square(item)
        output.append(y)
    
    print (output)
    _

    このソリューションには、最も単純なであるという利点があります。

    ...そしてそれでも最も危険使用される if あなたは正確にユーザーが何をするかわからない入力のために我慢。それ以外の場合、このソリューションは問題なく、最も簡単です。

    あなたの解決策は、多かれ少なかれこのカテゴリーに属すると思います。ユーザーがどのような入力を行い、何を行わないかを知っています。したがって、このソリューションまたは独自のソリューションを使用すると、次のようになります。

    _if not x and not str(x).isdigit():
    _

    サンプルソリューションがより単純であることを除いて、問題ありません


あなたのケースを考えると、上記の solution を使用して以下を取得できます。

_ [1, 9, 0, 81]
_

(補足:読みやすくするために、ソリューションを「正規のソリューション」のようにフォーマットするようにしています。こうすることで、同じ質問があり、将来このページにアクセスする人ができる可能性があります。より包括的で読みやすいソリューションを見つける)

18
Ian

Noneを使用して「このパラメーターが設定されていません」と通知しているので、isキーワードを使用してチェックする必要があるのはまさにそれです。

def square(x=None):
    if x is None:
        print "you have not entered x"
    else:
        y=x**2
        return y

タイプのチェックは、intだけでなく、すべての可能な入力タイプをチェックする必要があるため、面倒でエラーが発生しやすくなります。

8
Hannes Ovrén
if x is None:
   print 'x is None'
2
arnuga3

私が理解している限り、入力が与えられなかったケースをキャッチしたいと思います。

if x is None:
    ...

そしてそれが数ではない場合。 2つ目では、かなりの問題が発生します。将来、numpy-ndarraysなどを許可したい場合があるため、通常は、他のクラスを除外することを気にしないことをお勧めしますが、許可したいだけの場合はintfloatを使用して、

if isinstance(x, (int, float, ...)):
    ...

...は他の許可されたクラスを表します(多分DecimalまたはFractions)。

したがって、次のように書くことができます。

if x is not None and isinstance(x, (int, float)):
     return x**2
else:
     print "you have not entered x"

Noneintでもfloatでもないため、最初の条件を省略して次のように記述することもできます。

if isinstance(x, (int, float)):
     ...
1
MSeifert

すべての入力が互換性でなければならない単一の型を識別できる場合は、それをconvertして、例外を処理できます。

def square(x=None):
    try:
        return float(x)**2
    except TypeError:
        print "You did not enter a real number"
        return None # Explicit is better than implicit

これにはいくつかの利点があります。

  • これは、ユーザーが送信するものはすべてfloatと互換性があることを強制します。これは、任意の数値、数値を含む文字列('5.0')、またはfloatに変換できるその他のものにすることができます。 (floatインスタンスは変更されずに返されます。)
  • 簡単です。あなたの方法で起こっている奇妙な魔法はありません。ダックタイピングを壊しているわけではありません。あなたは物事を正しく機能させるためにあなたの要件を強制しているだけです。
  • 実際にタイプをチェックすることに伴う落とし穴に対して脆弱ではありません。発信者は、カスタムタイプがどのようにfloatに変換されるかを教えてくれます。 Pythonは__float__マジックメソッドを提供するため、ユーザーがエキゾチックなタイプを持っていて、関数を使用する必要がある場合、それらは沈められません。
  • それは慣用的です。経験豊富なPythonプログラマーは、この種のコードを期待します。これは、「許可よりも許しを求めるのが簡単」という原則に従います。

余談(多分):

Noneが無効な値である場合は、デフォルト値にしないでください。発信者に入力を強制するだけです。

def square(x):
    try:
        return float(x)**2
    except TypeError:
        print "You did not enter a real number"
        return None
1
jpmc26

Uはここで例外を処理できます。このようなコードを作成します

def square(x):
    if not x:
        print "you have not entered x"
    else:
        try:
            int(y)=x**2
            return y
        except TypeError:
            pass


list=[1, 3, 0 ,9]
output=[]
0
Dark Matter