2014-01-31 119 views
2

作爲初學計算機科學的學生,我被分配編寫一個函數,將偶數和奇數列表分類爲兩個子列表。等等...別投我票。我一直在學習自己的一點,並試驗列表理解和時間,並想知道我是否可以通過列表理解重新創建一些更具挑戰性的內容。列表理解子列表

我已經想出瞭如何使用列表理解來壓扁子列表,但不是相反。可能嗎?

def odd_even_filter(numbers): 
    even = [] 
    odd = [] 
    for i in numbers: 
     if i % 2 == 0: 
      even.append(i) 
     else: 
      odd.append(i) 
    return [even, odd] 

odd_even_filter([1, 2, 3, 4, 5, 6, 7, 8, 9]) 
>>[[2,4,6,7],[1,3,5,7,9]] 

只是試圖看看我是否可以採取一個單子列表並使用列表理解生成嵌套列表。它可能不值得,也不是蟒蛇的方式,而只是試驗。

+0

什麼是你的問題是什麼呢?如何用列表理解來做到這一點? –

回答

0

這是有效的,根本不容易閱讀,但它可能是範圍是子組的數量,2是偶數和奇數。

return [[ n for n in numbers if n % 2 == 0] if i == 0 else [ n for n in numbers if n % 2 != 0] for i in range(2)] 

通過timeit執行此操作,需要兩倍的時間。 devnull的答案也需要更長的時間。

def odd_even_filter(numbers): 
    even = [] 
    odd = [] 
    for i in numbers: 
     if i % 2 == 0: 
      even.append(i) 
     else: 
      odd.append(i) 
    return [even, odd] 

def odd_even_filter_2(numbers): 
    return [[ n for n in numbers if n % 2 == 0] if i == 0 else [ n for n in numbers if n % 2 != 0] for i in range(2)] 

def odd_even_filter_3(numbers): 
    even = [] 
    odd = [] 
    [ odd.append(n) if n % 2 != 0 else even.append(n) for n in numbers] 
    return [even,odd] 

print(timeit.timeit('odd_even_filter([1, 2, 3, 4, 5, 6, 7, 8, 9])', setup="from __main__ import odd_even_filter")) 
print(timeit.timeit('odd_even_filter_2([1, 2, 3, 4, 5, 6, 7, 8, 9])', setup="from __main__ import odd_even_filter_2")) 
print(timeit.timeit('odd_even_filter_3([1, 2, 3, 4, 5, 6, 7, 8, 9])', setup="from __main__ import odd_even_filter_3")) 

>>2.2804439414858675 
>>4.190625469924679 
>>3.0541580641135733 
1

代碼中的可讀性和緊湊性之間總是存在折衷。在這種情況下,我相信devnull的回答非常好。他使用列表解析和Python if表達式,在單行中產生非常可讀的內容。如果您的測試標準更嚴格,將條件分解爲自己的功能通常更有用。對於你的榜樣,這些將是:

def even(x): return x%2 == 0 
def odd(x) : return x%2 != 0 

,然後用它們來過濾出來的結果像這樣:

def oddEvenFilter(x): return [filter(even, x), filter(odd, x)] 

這些三行代碼,但在組合非常具有可讀性。

0

基於SSM的帖子:

>>> l = [1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>> [list(filter(lambda x: x%2==0, l)), list(filter(lambda x: x%2==1, l))] 
[[2, 4, 6, 8], [1, 3, 5, 7, 9]] 

該解決方案是緩慢的,但。

0

如果您的號碼在順序你甚至可以用切片:

>>> [r[1::2],r[2::2]] 
[[1, 3, 5, 7, 9], [2, 4, 6, 8]] 
>>> 
1

如果你的目標爭取在最短的,但Python的答案,怎麼樣?

odd = [i for i in numbers if i % 2] # this is O(n) 
even = list(set(numbers) - set(odd)) # this is O(n log n) 

低效的,但還是明確的替代方案是:

even = numbers - odd # this is O(n^2) 

的O(n)的替代(最好?)是:

odd = [i for i in numbers if i % 2] # this is O(n) 
even = [i for i in numbers if not i % 2] # this is O(n)