列出对子列表的理解

时间:2014-01-31 04:42:18

标签: python python-3.x list-comprehension

作为一名初学计算机科学专业的学生,​​我被分配编写一个功能,将偶数和奇数列表分成两个子列表。等等......不要投票给我。我一直在学习自己,并尝试使用列表理解和时间,并且想知道我是否可以使用列表理解来重新创建这一点来做一些更具挑战性的事情。

我已经弄清楚如何使用列表推导来展平子列表,但不是相反。有可能吗?

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]]

试着看看我是否可以使用列表推导来获取平面列表并生成嵌套列表。它可能不值得,而不是python方式,而只是试验。

5 个答案:

答案 0 :(得分:2)

如果你的目标是获得最短但更快速的回答,那该怎么办?

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)

答案 1 :(得分: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)]

这些是三行代码,但组合起来非常易读。

答案 2 :(得分: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

答案 3 :(得分: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]]

这个解决方案很慢。

答案 4 :(得分:0)

如果你的号码是顺序的,你甚至可以使用切片:

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