2016-07-20 51 views
4

我試圖創建一個函數,其中給定的值(作爲字符串傳遞)被檢查以查看數字的位數是4還是6,並且這是一個數字。在Python中使用IF,AND或OR與EQUAL操作數

我的第一個念頭是去與此代碼:

def number(x): 
    if (len(x) == (4 or 6)) and x.isdigit(): 
     print "True" 
    else: 
     print "False" 

只有上面這段代碼通過下面的第一個測試...我不明白爲什麼它通過這個,但沒有其他測試:

number("1234") 

只有當我分離出len()函數才能正常工作。

def number(x): 
    if (len(x) == 4 or len(x) == 6) and x.isdigit(): 
     print "True" 
    else: 
     print "False" 


## Checks 
number("1234") 
number("123456") 
number("abcd") 
number("abcdef") 
number("1") 
number("a") 

上述代碼通過了所有測試。

所以我的問題是:

  1. 這是怎麼回事?
  2. 任何方式來寫這個清潔的代碼?

感謝您的幫助!

**不是一個重複的問題,因爲雖然這個問題有關於布爾運算符的基本概念相同,但由於使用了len(),isdigit()以及如何最好地改進它(有人評論使用返回)。儘管如此,肯定會給另一個問題增加另一個觀點。

+4

提示:「(4或6)」自己評估什麼? 'len(x)'是否等於? –

+1

不重複。差遠了。是的,兩個問題都可以通過閱讀相同的手冊來解決,但不能重複。 –

回答

2

它有助於檢驗這一行的邏輯:

if (len(x) == (4 or 6)): 

The (4 or 6)子句包含邏輯or短路。值4爲true,因此將對其進行評估並返回到==關係比較。

or工作的方式是,其左手邊評估布爾真值,如果爲真,則返回其值。如果左邊不是布爾真,那麼評估右邊並返回其值。

由於4 or ...的左側在布爾意義上爲true,所以右側不會被評估。 Python甚至看不到4 or。如果左側值爲假值(例如0),則將評估or的右側。

要查看此功能,請嘗試print 4 or 6。輸出將是4.

因此,由於4是硬編碼的真值,因此您的比較在語義上與if (len(x) == 4)相同 - 也就是說,因爲4是真的,所以從不計算6。

我想你真的想知道的是,如果len(x)是4或6。你可以把該代碼在幾個方面:

if(len(x) == 4 or len(x) == 6 ... 

if(len(x) in (4,6) ... 
5

可以使用in運營商,像這樣:

def number(x): 
    if len(x) in (4, 6) and x.isdigit(): 
    print "True" 
else: 
    print "False" 

其中in檢查在給定的容器密封。請注意,4 or 6自己評估爲不合需要的東西,這就是爲什麼您的第一個代碼段失敗。您可以檢查出來的蟒蛇外殼:

>>> 4 or 6 
4 
1

你可能想寫

if (len(x) in (4, 6)) and x.isdigit(): 

而不是

if (len(x) == (4 or 6)) and x.isdigit(): 
2

簡短的回答:len(x) in [4, 6]len(x) == 4 or len(x) == 6

「或」是布爾或邏輯選擇。 (4或6)保證解析爲非零(真)值。在這種情況下,它解析爲4,所以你的測試用例通過。

+0

在閱讀你的回覆之後,我點了點頭 - 謝謝。 對於讀這個的人來說 - 我犯的嚴重錯誤並不是把OR看作布爾值。 – jhub1

1

問題出在您的or聲明中。

當您將其放入條件式中時,任何大於1的值都將評估爲True。所以(4 or 6)總是解析爲true。

您可以使用in上述聲明或者你可以只使用兩個==的:

if (len(x) == 4 or len(x) == 6) and x.isdigit()

這有點wordier,我覺得更容易閱讀。

1

我會繼續和回答

任何方式編寫更乾淨的代碼呢?

是的。 返回的布爾值,而不是打印字符串。

def number(x): 
    return len(x) in {4, 6} and x.isdigit() 

print(number("1234")) # True 

然後,在沒有字符串比較的if語句中使用你的方法很簡單。

+0

謝謝。爲了擴大這一點 - 如果你想要這兩個功能的時間,你會怎麼做?我在控制檯嘗試了[Python -m timeit「import simplified; simplified.number()] ...但它無效。simplified.py是此函數所在文件的名稱。 – jhub1

+0

不確定。從不使用'timeit',但我想說這更快,因爲沒有if-else條件 –