ifステートメント内のPythonの&&(論理AND)に相当するもの


830

これが私のコードです:

def front_back(a, b):
  # +++your code here+++
  if len(a) % 2 == 0 && len(b) % 2 == 0:
    return a[:(len(a)/2)] + b[:(len(b)/2)] + a[(len(a)/2):] + b[(len(b)/2):] 
  else:
    #todo! Not yet done. :P
  return

IF条件付きでエラーが発生します。
何が悪いのですか?


10
明らかにセルジオは彼のコードが壊れた理由を知りたがったが、質問のタイトルをもう少し読んだ。とにかく&&が利用できないのはなぜですか?==および!=が使用可能です(ただし、isとは異なりますが、そうではありません)。この構文を含めないのはなぜですか?個人の好み?
physicsmichael

5
@ vgm64:単一の側面を改善しない冗長な構文を含めるのはなぜですか?
Konrad Rudolph

27
不可解な「SyntaxError:無効な構文」を出力するのではなく、インタープリターがすべきであるように思えます-ユーザーが使用&&したことを検出し、and代わりにキーワードを使用する可能性があることをユーザーに提案します。同様のことが++、他の言語の一般的な演算子にも当てはまります。
ArtOfWarfare 2013

3
@physicsmichael "それを行うための明白な方法は1つ、できれば1つだけである必要があります。" import this
Nick T

3
@KonradRudolph言語の側面を完全に改善します。他の言語を使用したことがある人にとっては、より一貫性があり直感的です。この質問が存在し、トラフィックが多いという事実は、この問題が人々の共通の問題点であることを明確に強調しています。
jterm 2017

回答:


1473

and代わりにしたいでしょう&&


2
これに対して私は何をすべきですか:x == 'n'およびy == 'a'またはy == 'b'の場合:<何か>動作しますか?@ChristopheD
diffracteD

7
@diffracteD:標準の演算子の優先順位をオーバーライドする場合はかっこを使用します(ここで学習できます:ibiblio.org/g2swap/byteofpython/read/operator-precedence.html
ChristopheD

3
David Titarencoがカットアンドペーストの例を示したの
Alexx Roche

7
私は両方を入力した後、私はここに到着&&し、AND及び(小文字の単語をしたいためにのpythonを期待していないエラーが発生しましたand)。
Xeoncross

2
私はあなたが使う&表示されるはずだと思う:stackoverflow.com/questions/36921951/...
user1761806

229

Pythonの使用andor条件。

すなわち

if foo == 'abc' and bar == 'bac' or zoo == '123':
  # do something

5
Pythonもそうでないことを忘れないでください(まあ、!)
inspectorG4dget

9
あなたの例は、「(これとこれ)か」または「もしこれと(これ)」と評価されますか?
ジェフ

12
@ジェフあなたの最初の方法。and はより優先されorます。
14

1
@Bugeは、リンクしたテーブルで「または」が上位にあるように見えます
Matt

5
@Mattテーブルは優先順位が最も低いものから最も高いものへと進みます。ブール代数を学んだ方が、優先順位を覚えやすくなります。「or」は加算で、「and」は乗算です。
Michael Stroud 2017

48

IF条件付きでエラーが発生します。何が悪いのですか?

を取得する理由SyntaxError&&、Pythonに演算子がないためです。同様に||、Pythonの有効な演算子で!はありません

他の言語で知っている演算子の中には、Pythonでは別の名前を持つものがあります。論理演算子&&||は、実際にはと呼ばandorます。同様に、論理否定演算子!はと呼ばれnotます。

だからあなたはただ書くことができます:

if len(a) % 2 == 0 and len(b) % 2 == 0:

あるいは:

if not (len(a) % 2 or len(b) % 2):

いくつかの追加情報(役に立つかもしれません):

次の表に、演算子「同等」をまとめました。

+------------------------------+---------------------+
|  Operator (other languages)  |  Operator (Python)  |
+==============================+=====================+
|              &&              |         and         |
+------------------------------+---------------------+
|              ||              |         or          |
+------------------------------+---------------------+
|              !               |         not         |
+------------------------------+---------------------+

Pythonのドキュメントも参照してください:6.11。ブール演算

論理演算子の他に、Pythonにはビット単位/二項演算子もあります。

+--------------------+--------------------+
|  Logical operator  |  Bitwise operator  |
+====================+====================+
|        and         |         &          |
+--------------------+--------------------+
|         or         |         |          |
+--------------------+--------------------+

Pythonにはビット単位の否定はありません(ビット単位の逆演算子~だけですが、これはと同等ではありませんnot)。

6.6も参照してください単項算術演算とビット単位/二項演算、および6.7。バイナリ算術演算

論理演算子(他の多くの言語と同様)には、これらが短絡されるという利点があります。つまり、最初のオペランドが既に結果を定義している場合、2番目の演算子はまったく評価されません。

これを示すために、私は単に値を取り、それを出力し、再び返す関数を使用します。これは、printステートメントのために実際に何が評価されるかを確認するのに便利です。

>>> def print_and_return(value):
...     print(value)
...     return value

>>> res = print_and_return(False) and print_and_return(True)
False

ご覧のように、実行されるprintステートメントは1つだけなので、Pythonは実際には正しいオペランドを見さえしませんでした。

これは、2項演算子には当てはまりません。それらは常に両方のオペランドを評価します:

>>> res = print_and_return(False) & print_and_return(True);
False
True

ただし、最初のオペランドが十分でない場合は、当然、2番目の演算子が評価されます。

>>> res = print_and_return(True) and print_and_return(False);
True
False

これをまとめると、ここに別の表があります。

+-----------------+-------------------------+
|   Expression    |  Right side evaluated?  |
+=================+=========================+
| `True` and ...  |           Yes           |
+-----------------+-------------------------+
| `False` and ... |           No            |
+-----------------+-------------------------+
|  `True` or ...  |           No            |
+-----------------+-------------------------+
| `False` or ...  |           Yes           |
+-----------------+-------------------------+

TrueそしてFalse何を表すbool(left-hand-side)リターンを、彼らがしている必要はありませんTrueFalse、彼らは返す必要がありますTrueFalseときbool(1)それらに呼ばれています。

したがって、疑似コード(!)では、andand or関数は次のように機能します。

def and(expr1, expr2):
    left = evaluate(expr1)
    if bool(left):
        return evaluate(expr2)
    else:
        return left

def or(expr1, expr2):
    left = evaluate(expr1)
    if bool(left):
        return left
    else:
        return evaluate(expr2)

これはPythonコードではなく疑似コードであることに注意してください。Pythonでは、andまたはorというキーワードが原因で、呼び出される関数を作成できません。また、「evaluate」またはを使用しないでくださいif bool(...)

独自のクラスの動作をカスタマイズする

この暗黙的なbool呼び出しを使用して、クラスがandorおよびで動作する方法をカスタマイズできますnot

これをどのようにカスタマイズできるかを示すために、このクラスを使用します。これも、print何が起こっているかを追跡するためのものです。

class Test(object):
    def __init__(self, value):
        self.value = value

    def __bool__(self):
        print('__bool__ called on {!r}'.format(self))
        return bool(self.value)

    __nonzero__ = __bool__  # Python 2 compatibility

    def __repr__(self):
        return "{self.__class__.__name__}({self.value})".format(self=self)

それでは、これらの演算子と組み合わせてそのクラスで何が起こるか見てみましょう:

>>> if Test(True) and Test(False):
...     pass
__bool__ called on Test(True)
__bool__ called on Test(False)

>>> if Test(False) or Test(False):
...     pass
__bool__ called on Test(False)
__bool__ called on Test(False)

>>> if not Test(True):
...     pass
__bool__ called on Test(True)

__bool__メソッドがない場合、Pythonはオブジェクトに__len__メソッドがあるかどうか、およびゼロより大きい値を返すかどうかもチェックします。これは、シーケンスコンテナーを作成する場合に知っておくと便利です。

4.1も参照してください真理値テスト

NumPyの配列とサブクラス

おそらく元の質問の範囲を少し超えていますが、NumPy配列またはサブクラス(Pandas SeriesやDataFramesなど)を処理している場合は、暗黙的なbool呼び出しによって恐怖が発生しValueErrorます。

>>> import numpy as np
>>> arr = np.array([1,2,3])
>>> bool(arr)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
>>> arr and arr
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

>>> import pandas as pd
>>> s = pd.Series([1,2,3])
>>> bool(s)
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
>>> s and s
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

これらの場合、要素ごとに(または)実行するNumPyの論理関数関数を使用できます。andor

>>> np.logical_and(np.array([False,False,True,True]), np.array([True, False, True, False]))
array([False, False,  True, False])
>>> np.logical_or(np.array([False,False,True,True]), np.array([True, False, True, False]))
array([ True, False,  True,  True])

ブール配列だけを扱っている場合は、NumPyで2項演算子を使用することもできます。これらは要素ごとの(ただし2進数の)比較を実行します。

>>> np.array([False,False,True,True]) & np.array([True, False, True, False])
array([False, False,  True, False])
>>> np.array([False,False,True,True]) | np.array([True, False, True, False])
array([ True, False,  True,  True])

(1)

boolオペランドの呼び出しは戻るTrue必要Falseがあるか、完全に正しくない。これは、__bool__メソッドでブール値を返す必要がある最初のオペランドにすぎません。

class Test(object):
    def __init__(self, value):
        self.value = value

    def __bool__(self):
        return self.value

    __nonzero__ = __bool__  # Python 2 compatibility

    def __repr__(self):
        return "{self.__class__.__name__}({self.value})".format(self=self)

>>> x = Test(10) and Test(10)
TypeError: __bool__ should return bool, returned int
>>> x1 = Test(True) and Test(10)
>>> x2 = Test(False) and Test(10)

これandは、最初のオペランドが評価された場合に実際に最初のオペランドを返し、評価されたFalse場合にTrue2番目のオペランドを返すためです。

>>> x1
Test(10)
>>> x2
Test(False)

同様に、orしかし逆に:

>>> Test(True) or Test(10)
Test(True)
>>> Test(False) or Test(10)
Test(10)

ただし、ifステートメントでそれらを使用すると、if暗黙的boolに結果が呼び出されます。したがって、これらの細かい点はあなたには関係がないかもしれません。


36

2つのコメント:

  • Pythonの論理演算にとを使用andorます。
  • インデントには2の代わりに4つのスペースを使用します。コードは他の人のコードとほとんど同じに見えるので、後で感謝します。詳細については、PEP 8を参照してください。

10

CやC ++のような論理演算を実行するにはand、andorを使用ます。のように文字通りandあり&&orです||


この楽しい例を見てください、

Pythonでロジックゲートを構築したいとします。

def AND(a,b):
    return (a and b) #using and operator

def OR(a,b):
    return (a or b)  #using or operator

今それらを呼び出してみてください:

print AND(False, False)
print OR(True, False)

これは出力します:

False
True

お役に立てれば!


9

私は純粋に数学的な解決策を講じました:

def front_back(a, b):
  return a[:(len(a)+1)//2]+b[:(len(b)+1)//2]+a[(len(a)+1)//2:]+b[(len(b)+1)//2:]

7
これは実際の質問に対する答えではありません。
マシュー

5

おそらくこれはこのタスクに最適なコードではありませんが、機能しています-

def front_back(a, b):

 if len(a) % 2 == 0 and len(b) % 2 == 0:
    print a[:(len(a)/2)] + b[:(len(b)/2)] + a[(len(a)/2):] + b[(len(b)/2):]

 elif len(a) % 2 == 1 and len(b) % 2 == 0:
    print a[:(len(a)/2)+1] + b[:(len(b)/2)] + a[(len(a)/2)+1:] + b[(len(b)/2):] 

 elif len(a) % 2 == 0 and len(b) % 2 == 1:
     print a[:(len(a)/2)] + b[:(len(b)/2)+1] + a[(len(a)/2):] + b[(len(b)/2)+1:] 

 else :
     print a[:(len(a)/2)+1] + b[:(len(b)/2)+1] + a[(len(a)/2)+1:] + b[(len(b)/2)+1:]

-3

シングル&(ダブルで&&はなく)で十分です。または、トップの回答が示すように、「and」を使用できます。私はこれもパンダで見つけました

cities['Is wide and has saint name'] = (cities['Population'] > 1000000) 
& cities['City name'].apply(lambda name: name.startswith('San'))

「&」を「and」に置き換えても機能しません。


1
単一であり、式を短絡させません(最初の式の戻り値に関係なく両方が評価されることを意味します)
user528025

-4

おそらく&代わりに%の方が速くて読みやすい

その他のテスト偶数/奇数

xは偶数ですか?x%2 == 0

xは奇数ですか?x%2ではない== 0

たぶんビットワイズでより明確です1

xは奇数ですか?x&1

xは偶数ですか?x&1ではない(奇数ではない)

def front_back(a, b):
    # +++your code here+++
    if not len(a) & 1 and not len(b) & 1:
        return a[:(len(a)/2)] + b[:(len(b)/2)] + a[(len(a)/2):] + b[(len(b)/2):] 
    else:
        #todo! Not yet done. :P
    return

-4

条件付きでの「and」の使用。Jupyter Notebookにインポートするときにこれをよく使用します。

def find_local_py_scripts():
    import os # does not cost if already imported
    for entry in os.scandir('.'):
        # find files ending with .py
        if entry.is_file() and entry.name.endswith(".py") :
            print("- ", entry.name)
find_local_py_scripts()

-  googlenet_custom_layers.py
-  GoogLeNet_Inception_v1.py

14
この質問は約7年前に尋ねられ、回答されました。あなたの答えは、すでにここにあるそれらの答えに何を追加しますか?一般に、驚くほど新しい何かを言う場合を除いて、古い回答に新しい回答を追加しないでください。古い回答は、複数の年として測定されます。すでに適切な回答がある場合。
Jonathan Leffler 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.