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

Ran это через 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

Если вы стремитесь к кратчайшему, еще вещий ответ, как насчет?

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) 

Уплотнительное (п) альтернатива (лучше?) Будет:

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) 
Смежные вопросы