web-dev-qa-db-ja.com

IF、AND、ORとEQUALオペランドを組み合わせてPython

与えられた値(文字列として渡される)をチェックして、桁数が4または6であり、それが数値であるかどうかを確認する関数を作成しようとしています。

私の最初の衝動は、このコードで行くことでした:

def number(x):
    if (len(x) == (4 or 6)) and x.isdigit():
        print "True"
    else:
        print "False"

上記のコードは、以下の最初のテストのみに合格します...なぜこれに合格するのかわかりませんが、他のテストには合格しません。

number("1234")

Len()関数を分離した場合にのみ、正しく機能します。

def number(x):
    if (len(x) == 4 or len(x) == 6) and x.isdigit():
        print "True"
    else:
        print "False"


## Checks
number("1234")
number("123456")
number("abcd")
number("abcdef")
number("1")
number("a")

上記のコードはすべてのテストに合格しています。

だから私の質問は:

  1. 何が起きてる?
  2. このためのよりクリーンなコードを書く方法はありますか?

助けてくれてありがとう!

**この質問はブール演算子に関して同じ基本的な概念を持っていますが、len()、isdigit()の使用、およびそれを改善する最善の方法に関する追加の質問(誰かがコメントした)のために問題自体が異なるため、重複した質問ではありませんリターンの使用方法)。もちろん、他の質問に別の視点を追加します。

7
jhub1

この行のロジックを調べると役立ちます。

if (len(x) == (4 or 6)):

(4 or 6)句には、論理的なor短絡が含まれています。値4はtrueであるため、評価され、==リレーショナル比較に返されます。

orが機能する方法は、左側がブール値の真として評価され、trueの場合にその値が返されることです。左側がブール値trueではない場合、右側が評価され、その値が返されます。

4 or ...の左側はブール値でtrueであるため、右側は評価されません。 Pythonは4 orを過ぎても見えません。左側の値がfalse値(0など)の場合、orの右側が評価されます。

この動作を確認するには、print 4 or 6を試してください。出力は4になります。

したがって、4はハードコードされた真の値なので、比較はif (len(x) == 4)と意味的に同じです。つまり、4は真なので、6は評価されません。

あなたが本当に知りたいと思うのは、len(x)が4または6のどちらであるかです。これをいくつかの方法でコード化できます。

if(len(x) == 4 or len(x) == 6 ...

if(len(x) in (4,6) ...
5
DavidO

次のようにin演算子を使用できます。

def number(x):
    if len(x) in (4, 6) and x.isdigit():
    print "True"
else:
    print "False"

ここで、inは、指定されたコンテナー内の包含をチェックします。ご了承ください 4 or 6単独で望ましくないものとして評価します。そのため、最初のコードセグメントは失敗します。 python Shellで確認できます:

>>> 4 or 6
4
6
ifma

短い答え:len(x) in [4, 6]またはlen(x) == 4 or len(x) == 6

「または」はブール値、または論理的な選択です。 (4または6)は、ゼロ以外(真)の値に解決されることが保証されています。この場合は4に解決されるため、テストケースは成功します。

2
Charles Merriam

あなたはおそらく書きたかった

if (len(x) in (4, 6)) and x.isdigit():

の代わりに

if (len(x) == (4 or 6)) and x.isdigit(): 
1
jonas_toth

私は進んで答えます

このためのよりクリーンなコードを書く方法はありますか?

はい。 Return文字列を出力するのではなく、ブール値。

def number(x): 
    return len(x) in {4, 6} and x.isdigit()

print(number("1234")) # True

次に、文字列を比較せずにifステートメントでメソッドを使用するのは簡単です。

1
cricket_007

問題はあなたのorステートメントにあります。

条件付きの場合、1より大きい値はTrueと評価されます。したがって、_(4 or 6)_はalwaysをtrueに解決します。

上記のinステートメントを使用することも、2つの_==_を使用することもできます。

if (len(x) == 4 or len(x) == 6) and x.isdigit()

少し言葉が多いですが、読みやすいと思います。

0
Ares