web-dev-qa-db-ja.com

Ifステートメント内でのPythonの&&(logical-and)と同等のもの

これが私のコードです:

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条件でエラーが発生しました。何がおかしいのですか?

701
delete

&&の代わりにandが欲しいでしょう。

1254
ChristopheD

Pythonはandor条件式を使います。

すなわち.

if foo == 'abc' and bar == 'bac' or Zoo == '123':
  # do something
201
David Titarenco

二つのコメント:

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

IF条件でエラーが発生しました。何がおかしいのですか?

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

他の言語から知っているかもしれない演算子の中には、Pythonでは違う名前を持つものがあります。論理演算子&&および||は、実際にはandname__およびorname__と呼ばれています。同様に、論理否定演算子!notname__と呼ばれます。

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

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で、notname__と同等です)。

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は実際には正しいオペランドさえ見ませんでした。

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

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

しかし、最初のオペランドが足りない場合は、もちろん、2番目の演算子が評価されます。

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

これを要約すると、もう1つの表になります。

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

Truename__とFalsename__は、bool(left-hand-side)が返すものを表します。これらはTruename__またはFalsename__である必要はなく、Truename__が呼び出された場合はFalsename__またはboolname__を返す必要があります。

したがって、擬似コード(!)では、andname__およびorname__関数は次のように機能します。

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では、andname__またはorname__という名前の関数はキーワードなので作成できません。また、 "evaluate"やif bool(...)を使ってはいけません。

あなた自身のクラスの振る舞いをカスタマイズする

この暗黙のboolname__呼び出しは、クラスがandname__、orname__およびnotname__とどのように動作するかをカスタマイズするために使用できます。

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

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など)を扱っている場合は、boolname__暗黙的な呼び出しによってValueErrorname__が暗黙的に呼び出されます。

>>> 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のlogicalとfunctionを使うことができます。これは要素ごとにandname__(またはorname__)を実行します。

>>> 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])

boolean配列だけを扱っているのであれば、NumPyで二項演算子を使うこともできます。これらは要素ごとの比較を行います(しかし二項演算も行います)。

>>> 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)

オペランドに対するboolname__呼び出しがTruename__またはFalsename__を返さなければならないことは完全には正しくありません。 __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)

これは、最初のオペランドがandname__と評価された場合はFalsename__が実際に最初のオペランドを返し、次にTruename__と評価された場合は2番目のオペランドを返すためです。

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

orname__も同様ですが、その逆です。

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

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

19
MSeifert

私は純粋に数学的な解を求めました:

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:]
10
Big Red

C、C++のように論理演算を実行するには、andおよびorを使用します。文字通りのように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

これが助けになることを願います

8
geekidharsh

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

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:]
5

Pythonの "If文"では、and or or not _を使用します。これらは、他のプログラミング言語で使用されている&&、||、!論理演算子と同等です。

0
masterpianist