2014-01-31 93 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)