2016-09-18 16 views
0

使用一行循環,甚至是嵌套循環在Python中總是一個好習慣?我看到很多人都喜歡「單行」,但對我而言,他們有時候很難閱讀,特別是如果我們談論嵌套循環。Python中單行語句的用處

而且大多數我見過的嵌套循環遠超過每行推薦的79個字符。

所以我想知道,如果「單行」提供額外的東西除了緊湊?他們可能會使用更少的內存嗎?

+0

取決於具體的一行。某些Python結構(例如:list comprehensions)可能會被解釋器優化,以產生「更好」的機器代碼,如果您編寫了一個正常的for-loop來填充列表。然而,正如你指出的那樣,如果你將代碼過度複雜化,代碼的可讀性會受到影響,並且程序員的工作是決定代碼變得無法讀取(因此不可維護)的程度。 – UnholySheep

+0

如果能夠顯示某些難以理解的理解,將會有所幫助。通常它可以通過使用正確的命名和一些空格來補救。但沒有具體的樣本就很難證明。 –

+0

看看我的例子中的堆疊列表理解......即使它技術上是 – NaN

回答

5

是的,他們能更快地很容易,因爲更多的代碼可以用C運行(在顯式循環所有的緊急措施必須是可用來解釋器,在一個班輪列表理解它不必)。還有避免了這一切.append方法呼叫的方法,查找等。在列表理解的開銷:

import timeit 


def f1(): 
    result = [] 
    for x in range(100): 
     for y in range(100): 
      result.append(x * y) 
    return result 


def f2(): 
    return [x * y for y in range(100) for x in range(100)] 


print('loop: ', timeit.timeit(f1, number=1000)) 
print('oneliner:', timeit.timeit(f2, number=1000)) 

結果(Python 3中):

loop: 1.2545137699926272 
oneliner: 0.6745600730064325 
+0

很好的答案,正是我所期待的。看起來是時候我深入瞭解列表理解並正確地學習它們。出於好奇:如果我遇到超過79個字符的PEP推薦的長嵌套循環? (我知道我只能指定迭代器'x'或類似的東西來保持它的簡短,但如果即使這樣也會超過79個字符) – narn

+0

[您可以在列表解析中使用換行符](http://stackoverflow.com /問題/ 5809059 /續行換列表內涵,或發電機表達式式的Python)。笛卡兒嵌套循環的另一種常見技術是使用['itertools.product'](https://docs.python.org/3/library/itertools.html#itertools.product)而不是嵌套循環。 –

1

取決於一襯墊,一些可以是更加有效和非常可讀的。

以列表理解爲例。比方說,你要採取一切數字1到10,輸出乘以他們的產品的清單2.

輸入:[1,2,3,...,9,10]
輸出:[2,4,6,...,18,20]

你可以做一個for循環,如下所示:

output = [] 
for i in range(1, 11): 
    output.append(i*2) 

或者你也可以使用列表理解:

[i*2 for i in range(1,11)] 

你會看到第l理解速度快得多,而且很可讀。

同樣可以說,對於字典理解,設定理解和生成器表達式。只要是可以理解的,我們極力鼓勵使用map()filter()

0

討論......他們都這樣做。

「A」列表理解...吸菸的一行... 「B」同樣的事情,但你可以提供一個列表理解中的註釋......它仍然在技術上是一個班輪 「 c'是傳統方法。 如果速度是一個問題,我不太擔心速度,除非我每天執行相同的任務,而且需要很長時間才能完成。當你談論微或納秒時比較速度可能會引起學術界的興趣,但它不會影響絕大多數用戶。 我總是投票表達清晰的代碼的緊湊性。

a = [i**2 for i in range(20) if i > 5 and i < 10] 

b = [i**2    # do this 
    for i in range(20) # using these 
    if (i > 5) and  # where this and 
     (i < 10)  # this is good 
    ] 

c = [] 
for i in range(20): 
    if (i > 5) and (i < 10): 
     c.append(i**2) 

EDIT 產生的數字範圍的產物給出的例子,是一個很好的指標,該oneliner不必是問題,但所使用的方法來獲得的結果。我將說明如何確定僅使用10個值的產品...如果您喜歡,請嘗試使用100。我會以完整的格式完成它,但如果需要的話,可以將所有內容都減少到一個字符串(不包括進口)。

>>> import numpy as np 
>>> a = np.arange(10) 
>>> b = np.arange(10).reshape(10,1) 
>>> a 
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) 
>>> b 
array([[0], 
     [1], 
     [2], 
     [3], 
     [4], 
     [5], 
     [6], 
     [7], 
     [8], 
     [9]]) 
>>> a*b 
array([[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
     [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 
     [ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18], 
     [ 0, 3, 6, 9, 12, 15, 18, 21, 24, 27], 
     [ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36], 
     [ 0, 5, 10, 15, 20, 25, 30, 35, 40, 45], 
     [ 0, 6, 12, 18, 24, 30, 36, 42, 48, 54], 
     [ 0, 7, 14, 21, 28, 35, 42, 49, 56, 63], 
     [ 0, 8, 16, 24, 32, 40, 48, 56, 64, 72], 
     [ 0, 9, 18, 27, 36, 45, 54, 63, 72, 81]]) 

或作爲一襯墊

>>> out = np.arange(10) * np.arange(10).reshape(10,1) 

,當然也有內置函數來做到這一點沒有充分表達我已經表明。

要點是,速度並不是一切。應該首先考慮清晰的代碼和選擇正確的工具來完成這項工作。

+0

'如果我> 5和我< 10' ->'如果5

+0

查看我的附錄以顯示更好的選擇。當數據輸入非常大時,此選項可以很好地進行縮放......這是另一個考慮因素。並非所有的方法都是統一的,而且通常取決於數據大小。 – NaN

+1

如何說「使用numpy」替代列表解析? numpy是一個專門用於數值計算的(第三方)庫,而列表解析(和其他單行程序)可以是通用的,用於許多與數值計算 – UnholySheep