гинеколог отечественного веб-дизайна (ao_mmm) wrote,
гинеколог отечественного веб-дизайна
ao_mmm

Разделить список на 2 одной сточкой. Python

К примеру, есть список чисел и надо разделить его на два списка: список чётных и список нечётных (а вообще условие деления и исходный список могут быть любыми). Один нюанс: разделить надо одним выражением.

lst = range(0, 20)
odds, evens = ....


Пока придумалось только такое:
# императивщино-функциональщина с хаком и оопом
odds, evens = map(lambda x, a=[], b=[]: (x % 2 and a.append(x) or b.append(x)) or (a, b), lst)[0]


Списки a и b создаются только при определении лямбды. Лямбда действует с побочным эффектом -- модифицирует a и b и возвращает их кортеж. Мы получаем список одинаковых результатов, но все элементы этого списка -- кортежи ссылок на одни и те же a и b. То есть память по идее расходуется не сильно.

# функциональщина
odds, evens = reduce(lambda (a, b), x: x % 2 and (a + [x], b) or (a, b + [x]), lst, ([], []))


Вроде и объяснять-то нечего.


Upd: сравнение четырёх разных вариантов:
def listsplit1(lst, cond):  # 100004 function calls in 0.785 CPU seconds
    a, b = [], []
    for x in lst:
        if cond(x):
            a.append(x)
        else:
            b.append(x)
    return a, b
 
def listsplit2(lst, cond):  # 175005 function calls in 1.423 CPU seconds
    return map(lambda x, a=[], b=[]: (cond(x) and a.append(x) or b.append(x)) or (a, b), lst)[0]            
 
def listsplit3(lst, cond):  # 50005 function calls in 17.007 CPU seconds 
    return reduce(lambda (a, b), x: x % 2 and (a + [x], b) or (a, b + [x]), lst, ([], []))
 
def listsplit4(lst, cond):  # 100004 function calls in 0.764 CPU seconds 
    return [x for x in lst if cond(x)], [x for x in lst if not cond(x)]

Методика измерения (Python 2.5.2 (r252:60911, Feb 21 2008, 13:11:45) [MSC v.1310 32 bit (Intel)] on win32):
import profile
for i in range(4):
    profile.run('listsplit%d' % (i + 1) + '(xrange(50000), lambda x: x % 2)')
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 3 comments