IF koşulunda bir hata alıyorum. Neyi yanlış yapıyorum?
Bir almanızın nedeni Python'da operatör SyntaxError
olmamasıdır &&
. Aynı şekilde ||
ve !
vardır geçersiz Python operatörler.
Diğer dillerden tanıdığınız operatörlerin bazılarının Python'da farklı bir adı vardır. Mantıksal operatörler &&
ve ||
aslında denir and
ve or
. Aynı şekilde mantıksal olumsuzlama operatörü !
de çağrılır not
.
Böylece şunu yazabilirsiniz:
if len(a) % 2 == 0 and len(b) % 2 == 0:
ya da:
if not (len(a) % 2 or len(b) % 2):
Bazı ek bilgiler (kullanışlı olabilir):
Bu tabloda operatörün "eşdeğerlerini" özetledim:
+------------------------------+---------------------+
| Operator (other languages) | Operator (Python) |
+==============================+=====================+
| && | and |
+------------------------------+---------------------+
| || | or |
+------------------------------+---------------------+
| ! | not |
+------------------------------+---------------------+
Ayrıca bkz. Python belgeleri: 6.11. Boole işlemleri .
Python mantıksal operatörlerinin yanı sıra bitsel / ikili operatörlere de sahiptir:
+--------------------+--------------------+
| Logical operator | Bitwise operator |
+====================+====================+
| and | & |
+--------------------+--------------------+
| or | | |
+--------------------+--------------------+
Python'da bitsel bir olumsuzlama yoktur (sadece bitsel ters operatör ~
- ancak bu eşdeğer değildirnot
).
Ayrıca bkz.6.6. Tekli aritmetik ve bitsel / ikili işlemler ve 6.7. İkili aritmetik işlemler .
Mantıksal operatörler (diğer birçok dilde olduğu gibi) bunların kısa devre yapma avantajına sahiptir. Bu, eğer ilk işlenen sonucu zaten tanımladıysa, ikinci operatör hiç değerlendirilmez.
Bunu göstermek için, basitçe bir değer alan, basan ve tekrar döndüren bir fonksiyon kullanıyorum. Bu, baskı ifadeleri nedeniyle gerçekte neyin değerlendirildiğini görmek için kullanışlıdır:
>>> def print_and_return(value):
... print(value)
... return value
>>> res = print_and_return(False) and print_and_return(True)
False
Gördüğünüz gibi, yalnızca bir baskı ifadesi yürütüldü, bu yüzden Python gerçekten doğru işlenene bile bakmadı.
İkili operatörler için durum böyle değildir. Bunlar her iki işleneni de daima değerlendirir:
>>> res = print_and_return(False) & print_and_return(True);
False
True
Ancak ilk işlenen yeterli değilse, elbette, ikinci operatör değerlendirilir:
>>> res = print_and_return(True) and print_and_return(False);
True
False
Bunu özetlemek gerekirse başka bir Tablo:
+-----------------+-------------------------+
| Expression | Right side evaluated? |
+=================+=========================+
| `True` and ... | Yes |
+-----------------+-------------------------+
| `False` and ... | No |
+-----------------+-------------------------+
| `True` or ... | No |
+-----------------+-------------------------+
| `False` or ... | Yes |
+-----------------+-------------------------+
True
Ve False
neyi temsil bool(left-hand-side)
, bunlar olmak zorunda değilsiniz döner True
veya False
onlar sadece dönmek gerekir, True
ya da False
ne zaman bool
onlara (1) üzerine denir.
Pseudo-Code (!) 'Da and
ve or
işlevleri aşağıdaki gibi çalışır:
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)
Bunun Python kodu değil, sözde kod olduğunu unutmayın. Python'da, adlandırılan işlevler oluşturamazsınız and
veya or
bunlar anahtar kelimelerdir. Ayrıca asla "değerlendirme" veya kullanmamalısınız if bool(...)
.
Kendi sınıflarınızın davranışını özelleştirme
Bu örtülü bool
çağrı dersleriniz ile nasıl davrandığını özelleştirmek için kullanılabilir and
, or
ve not
.
Bunun nasıl özelleştirilebileceğini göstermek print
için, neler olduğunu izlemek için bir şey olan bu sınıfı kullanıyorum :
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)
Şimdi bu operatörle birlikte bu sınıfta neler olduğunu görelim:
>>> 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)
Bir __bool__
yönteminiz yoksa, Python nesnenin bir __len__
yöntemi olup olmadığını ve sıfırdan büyük bir değer döndürüp döndürmediğini de kontrol eder . Bir dizi kabı oluşturmanız durumunda bunu bilmek faydalı olabilir.
Ayrıca bakınız 4.1. Gerçek Değer Testi .
NumPy dizileri ve alt sınıfları
Muhtemelen orijinal sorunun kapsamının biraz ötesinde, ancak NumPy dizileri veya alt sınıflarıyla (Pandas Serisi veya DataFrames gibi) uğraşıyorsanız, örtülü bool
çağrı korkutucuyu yükseltir 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().
Bu durumlarda, bir öğe (veya ) gerçekleştiren NumPy'nin mantıksal ve işlevini kullanabilirsiniz :and
or
>>> 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])
Yalnızca boole dizileriyle uğraşıyorsanız , NumPy ile ikili işleçleri de kullanabilirsiniz, bunlar öğe bazında (ama aynı zamanda ikili) karşılaştırmalar gerçekleştirir:
>>> 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)
İşlenenlerden gelen bool
çağrının geri dönmesi True
veya False
tamamen doğru olmaması gerekir. Bu, __bool__
yönteminde bir boole döndürmesi gereken ilk işlenen :
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)
Çünkü and
ilk işlenen değerlendirilirse ilk işleneni döndürür ve False
değerlendirirse True
ikinci işleneni döndürür:
>>> x1
Test(10)
>>> x2
Test(False)
Benzer şekilde or
ama tam tersi:
>>> Test(True) or Test(10)
Test(True)
>>> Test(False) or Test(10)
Test(10)
Ancak bunları bir if
ifadede kullanırsanız sonuç if
da dolaylı olarak çağrılır bool
. Dolayısıyla bu ince noktalar sizin için uygun olmayabilir.