2013-04-23 60 views
4

我想在一個MxN矩陣上做一個非常簡單的操作。如果矩陣中的其中一個元素包含零,我想將該元素所在的整行置零。我實施了可能是我未經訓練的頭腦可以設計的最笨重和最不尋常的pythonic解決方案。我知道有必須使用列表理解,是一個單向或來電,來圖(),但我無法想象的東西比我的野蠻嘗試清潔劑如下:一個人如何使這個代碼更Pythonic?

def has_zero(row): 
    for i in row: 
     if not i: 
      return True 
    return False 

def make_row_of_zeros(numColumns): 
    row = [] 
    for i in range(numColumns): 
     row.append(0) 
    return row 

def zeroify_if_has_zero(matrix): 
    columns = len(matrix[0]) 
    for i in range(len(matrix)): #making all you experts cringe! Sorry! 
     if has_zero(matrix[i]): 
      matrix[i] = make_row_of_zeros(columns) 
    return matrix 
+4

你使用numpy數組/矩陣嗎? (如果沒有,你絕對應該) – eudoxos 2013-04-23 06:50:21

+4

應該發佈在http://codereview.stackexchange.com/上。 – JeromeJ 2013-04-23 06:54:23

+0

@JeromeJ有沒有辦法重新發布?事實上,它更像是一個風格問題而不是一個錯誤,它使它成爲codereview的標準嗎? – Thalatta 2013-04-23 06:59:56

回答

9

圭多認爲沒有Python的變異,並返回變異的值,所以你有兩個選擇。

返回一個新的矩陣

def zeroify_if_has_zero(matrix): 
    return [[0]*len(row) if 0 in row else row for row in matrix] 

不同誘變(就地)版本*運營商一起

def zeroify_if_has_zero(matrix): 
    matrix[:] = [[0]*len(row) if 0 in row else row for row in matrix] 
+0

這就是我在說的!謝謝你,先生。 – Thalatta 2013-04-23 06:52:28

+2

請注意,這將返回一個新構造的矩陣,而不是修改原始。這可能是也可能不是你想要的。 – blubb 2013-04-23 06:53:19

+2

@blubb,返回_and_變異不是pythonic。你應該做一個或另一個 – 2013-04-23 06:54:13

1

使用列表內涵。例如。

def make_row_of_zeros(numColumns): 
    return [0] * numColumns 
2

在你的兩個第一功能的Python內置支持。你可以重寫你的簡單包裝那些,或者只是內聯的膽量:與列表理解

def has_zero(row): 
    return not all(row) # this works because 0 is falsey 

def make_row_of_zeros(numColumns) 
    return [0] * numColumns 

你可以做最後的(和整個事情內嵌),如果你想:

def zeroify_if_has_zero(matrix): 
    return [row if all(row) else [0] * len(row) for row in matrix] 
1

另一個對於make_row_of_zeros功能的解決方案可能是:

def make_row_of_zeros(numColumns): 
    return list(itertools.repeat(0, numColumns)) 

但是你真的需要一個功能? 從我的角度來看,我的命題和蘇雷什的命題都不需要;他們是自我解釋的。

0

除了所有其他線索,如果您使用的是您的代碼,那麼除非您需要使用range生成的列表,否則請使用xrange