2015-10-31 244 views
3

我有一個布爾數組,現在我想交換這些條目的數字。遍歷數組

False => 0 
True => 1 

我寫了兩段不同的代碼,我想知道哪一段更好,爲什麼。這不是關於實際解決問題,而是關於學習。

arr = [[True,False],[False,True],[True,True]] 

for i,row in enumerate(arr): 
    for j,entry in enumerate(row): 
     if entry: 
      arr[i][j] = 1 
     else: 
      arr[i][j] = 0 
print(arr) 

而第二種方法:

arr = [[True,False],[False,True],[True,True]] 

for i in range(len(arr)): 
    for j in range(len(arr[i])): 
     if arr[i][j]: 
      arr[i][j] = 1 
     else: 
      arr[i][j] = 0  
print(arr) 

,我讀了有辦法與進口itertools或類似做到這一點。如果可以用「板載工具」來完成,我真的不喜歡導入東西,但是我應該用它來解決這個問題嗎?

+2

絕對選項A;遍歷範圍(len(...))'不是pythonic。 – jonrsharpe

+0

非常感謝。那是我正在尋找的答案! – Swift

回答

9

讓我們來定義你的數組:

>>> arr = [[True,False],[False,True],[True,True]] 

現在,讓我們轉換布爾整數:

>>> [[int(i) for i in row] for row in arr] 
[[1, 0], [0, 1], [1, 1]] 

另外,如果我們想更靈活的什麼被取代的,我們可以用一個三元語句:

>>> [[1 if i else 0 for i in row] for row in arr] 
[[1, 0], [0, 1], [1, 1]] 
+1

打敗我,更優雅,我只是做了'[(lambda x:[int(y)for y in x])(i)因爲我在foo]' - 我不知道爲什麼我的大腦關機這麼辛苦,我不只是做你做的:)星期五結束的一天必須是 –

+0

也許'int(bool(i))'而不是三元? – ekhumoro

+1

John1024。非常感謝您在最後部分加入。因爲稍後我可能想使用一些其他符號而不是1和0:D – Swift

3

如果你想留在一個for循環(例如因爲你想改變現有的數組而不是創建一個新的數組),你應該簡化代碼。

我想先通過刪除索引(也沒有必要爲它,因爲它修改的行不是一個嵌套的數組更簡單)簡化了外部循環:

for row in arr: 
    for j, entry in enumerate(row): 
     if entry: 
      row[j] = 1 
     else: 
      row[j] = 0 

這類簡單的if語句可以通常使用if表達式進行簡化:

row[j] = 1 if entry else 0 

但在這種情況下,我們可以做得更好。 bool是的一個子類int(即所有bool的是int‘峯),和TrueFalse被定義爲恰好10分別 - 如果您向下滾動到PEP 285(https://www.python.org/dev/peps/pep-0285/)的說明書中部分你’我們會發現這種等價不是偶然的,而是通過設計非常重要。

因此,我們可以使用int構造搶底層整數值[*],因爲int(True) == 1int(False) == 0,如果 - 表達式可以簡化爲:

row[j] = int(entry) 

[*]技術上這是一個明確的上溯造型到一個基類,而不是轉換構造..

簡化代碼:

for row in arr: 
    for j, entry in enumerate(row): 
     row[j] = int(entry)