IF koşulunda bir hata alıyorum. Neyi yanlış yapıyorum?
Bir almanızın nedeni Python'da operatör SyntaxErrorolmaması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 andve 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 |
+-----------------+-------------------------+
TrueVe Falseneyi temsil bool(left-hand-side), bunlar olmak zorunda değilsiniz döner Trueveya Falseonlar sadece dönmek gerekir, Trueya da Falsene zaman boolonlara (1) üzerine denir.
Pseudo-Code (!) 'Da andve oriş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 andveya orbunlar 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, orve not.
Bunun nasıl özelleştirilebileceğini göstermek printiç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 :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])
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 Trueveya Falsetamamen 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ü andilk işlenen değerlendirilirse ilk işleneni döndürür ve Falsedeğerlendirirse Trueikinci işleneni döndürür:
>>> x1
Test(10)
>>> x2
Test(False)
Benzer şekilde orama tam tersi:
>>> Test(True) or Test(10)
Test(True)
>>> Test(False) or Test(10)
Test(10)
Ancak bunları bir ififadede kullanırsanız sonuç ifda dolaylı olarak çağrılır bool. Dolayısıyla bu ince noktalar sizin için uygun olmayabilir.