20

if notの発言について質問Python 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

これは機能しますが、少し扱いに​​くい方法のようです。誰かが別の方法を持っているなら、私はとても感謝しています。

4

6 に答える 6

18

問題

あなたはそれを正しく理解しています。not 0(および もnot 0.0) に戻りTrueますPython。これを確認するために簡単なテストを実行できます。

a = not 0
print(a)

Result: True

このように、問題が説明されています。この行:

if not x:

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


ソリューション

この問題を解決するには、いくつかの方法があります。最良の解決策と思われるものから、可​​能な最後の解決策まで、それらをリストします。


  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引数が数値かどうかをチェックするための抽象クラスです (これを指摘してくれたCopperfieldxの功績によるものです)。

    Python 標準ライブラリ ドキュメントからの抜粋では、複素数を除いて、必要なものだけが説明されています。

    クラス 番号.Number

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

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

    このようにして、definitionof を希望どおりにsquare 正確に記述します。このソリューションは、その包括性のおかげで最良のソリューションだと思います。


  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
    

    必要に応じて、含めるまたは除外するさまざまなデータ型について、上記の条件を簡単に変更/拡張できます。このソリューションは、有効性チェックのカスタマイズのおかげで 、 2 番目に優れていると思います。

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


  1. 不可能なケースを処理しない: ユーザーがinput として提示しないものを知っています。

    2番目のソリューションのように処理したいデータ型ではなく、ユーザーが入力しないデータ型を知っている場合は、もっと大まかに考えてください。次のように、より緩い条件チェックを行うことができます。

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

    このソリューションは、最も単純でありながら強力なチェック機能の 1 つであるため、 3 番目に優れていると思います。

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


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

    たとえば、x が常にintorであることがわかっている場合None、可能な入力エラーは- のみであり、次のような場合にのみ評価されることNoneを回避するロジックを単純に記述できます。yxNone

    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 not x and not str(x).isdigit():
    

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


あなたの場合、上記の解決策を使用して以下を取得できます。

 [1, 9, 0, 81]

(補足: 読みやすくするために、解決策を「正規の解決策」のようにフォーマットするようにしています。このようにして、同じ質問を持ち、将来このページにアクセスする人は、より包括的で解決策を見つけることができるかもしれません。可読)

于 2016-02-23T08:56:29.400 に答える
8

「このパラメーターが設定されていません」というシグナルを送信するために使用しているため、キーワードNoneを使用して確認する必要があるのはまさにそれです。is

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

型のチェックは煩雑であり、エラーが発生しやすくなります。なぜならint.

于 2016-02-23T09:02:56.290 に答える
1

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

if x is None:
    ...

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

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"

Noneは anintでも a でもないのでfloat、最初の条件を省略して次のように書くこともできます。

if isinstance(x, (int, float)):
     ...
于 2016-02-23T09:13:15.547 に答える
1

すべての入力が互換性を持つ必要がある単一の型を特定できる場合は、それを変換して例外を処理できます。

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
于 2016-04-27T23:36:25.157 に答える