Bir if ifadesinde Python'un && (mantıksal ve ve) eşdeğeri


830

İşte benim kod:

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 koşulunda bir hata alıyorum .
Neyi yanlış yapıyorum?


10
Açıkçası Sergio, kodunun neden kırıldığını bilmek istedi, ancak sorunun başlığını biraz daha okudum. Neden && niçin ulaşamayacaksınız? == ve! = kullanılabilir (ama biliyorum ve değildir, biliyorum). Neden bu sözdizimini eklemiyorsun? Kişisel tercih?
physicsmichael

5
@ vgm64: Neden tek bir yönü iyileştirmeyen gereksiz sözdizimi dahil edilmeli?
Konrad Rudolph

27
Bana öyle geliyor ki, yorumlayıcı şifreli bir "Sözdizimi Hatası: geçersiz sözdizimi" yazdırmak yerine, kullanıcının kullandığını tespit etmeli &&ve andbunun yerine anahtar kelimeyi kullanmak isteyebileceklerini önermelidir. Aynı şey ++ve diğer dillerdeki diğer yaygın operatörler için de geçerlidir.
ArtOfWarfare

3
@physicsmichael "bunu yapmanın tek ve tercihen tek, açık bir yolu olmalı." import this
Nick T

3
@KonradRudolph Dilin yönlerini kesinlikle geliştirir. Başka bir dil kullanan herkes için daha tutarlı ve sezgiseldir. bu sorunun var olduğu ve trafiği olduğu kadar çok insanın da bu sorunu açıkça vurguladığı bir konudur.
jterm

Yanıtlar:


1472

Bunun andyerine istersiniz &&.


2
bunun için ne yapmalıyım: eğer x == 'n' ve y == 'a' veya y == 'b': <bir şeyler yap> Çalışacak mı? @ChristopheD
diffracteD

7
@diffracteD: Standart operatör önceliğini geçersiz kılmak istiyorsanız parantez kullanın (buradan öğrenebilirsiniz: ibiblio.org/g2swap/byteofpython/read/operator-precedence.html )
ChristopheD


7
Her ikisi de yazdı &&ve ANDbir hata var (python küçük harfli kelime beklemek değil) buraya geldi and.
Xeoncross

2
Sanırım kullanmalısın & Bakınız: stackoverflow.com/questions/36921951/…
user1761806

229

Python kullanımları andve orkoşulları.

yani

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

5
Python'un da olmadığını unutmayın (iyi, ve!)
inspectorG4dget

9
Örneğiniz "(bu ve şuysa) ya da şuysa" VEYA "ve (şu ya da şu)" olarak değerlendiriyor mu?
Jeff

12
@ Jeff İlk yolun. and daha yüksek önceliğe sahiptir or.
Buge

1
@Buge, bağlandığınız tabloda "veya" gibi görünüyor
Matt

5
@Matt tablo en düşük öncelikli değerden en yüksek düzeye geçer. Boole cebirini incelediyseniz önceliği hatırlamak daha kolaydır; "veya" toplama ve "ve" çarpmadır.
Michael Stroud

48

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.


36

İki yorum:

  • Python'da mantıksal işlemler için andve kullanın or.
  • Girintiyi 2 yerine 4 boşluk kullanın. Daha sonra kendinize teşekkür edeceksiniz çünkü kodunuz herkesin koduyla hemen hemen aynı görünecektir. Daha fazla bilgi için PEP 8'e bakınız.

10

andVeor C, C ++ gibi mantıksal işlemleri gerçekleştirmek için kullanın . Gibi tam anlamıyla andbir &&ve orbir|| .


Bu eğlenceli örneğe bir göz atın,

Python'da Mantık Kapıları inşa etmek istediğinizi varsayalım:

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

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

Şimdi onları aramayı deneyin:

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

Bu çıktı:

False
True

Bu yardımcı olur umarım!


9

Tamamen matematiksel bir çözümle gittim:

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
Bu asıl sorunun cevabı değil.
Matthew,

5

Muhtemelen bu bu görev için en iyi kod değil, ama çalışıyor -

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

Tek bir &(çift değil &&) yeterlidir ya da üstteki cevabın 've' kullanabileceğinizi gösterir. Bunu pandalarda da buldum

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

"&" ifadesini "ve" ile değiştirirsek, çalışmaz.


1
Tek ve ifadeyi kısa devre yapmaz (ilk ifadenin dönüş değerinden bağımsız olarak her ikisi de değerlendirilecektir)
user528025

-4

belki ve bunun yerine% daha hızlıdır ve okunabilirliği korur

diğer testler çift / tek

x eşit mi? x% 2 == 0

x garip mi? x% 2 == 0 değil

belki bitsel ve 1 ile daha açık

x garip mi? x ve 1

x eşit mi? x & 1 değil (tek değil)

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

Koşullu olarak "ve" kullanımı. Bunu sık sık Jupyter Notebook'a aktarırken kullanıyorum:

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
Bu soru neredeyse 7 yıl önce sorulmuş ve cevaplanmıştır. Cevabınız zaten burada bulunan cevaplara ne katıyor? Genel olarak, şaşırtıcı bir şekilde söyleyecek yeni bir şeyiniz yoksa, halihazırda iyi yanıtlar olduğunda eski bir soruya - eski, birden çok yıl olarak ölçüldüğünde - yeni bir cevap eklememelisiniz.
Jonathan Leffler
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.