Форум сайта python.su
res += [v for v in vals if bool_func(v)]
vals = [v for v in vals if not bool_func(v)]
Офлайн
а bool_func тяжелая?
Если да -
tmp = [(v, bool_func(v)) for v in vals]
res += [v[0] for v in tmp if v[1]]
vals = [v[0] for v in tmp if not v[1]]
Офлайн
bool_func - лёгкая, а элементы v - это кортежи и могут быть большие. len(vals) не большой около двух тыщ.
Я больше всего боялся что сами кортежи начнут копироваться, а сейчас присмотрелся вроде нет, говоря языком си только указатели копируются. Такой положение вещей меня устраивает в любом варианте.
Офф топ. Вот понимать бы как в питоне память утилизируется, я на это опять же смотрю с точки зрения создания оптимального кода. Может есть где почитать про это?
Офлайн
Если по простому - есть два этапа.
1. Когда счетчик ссылок становится равным 0 - объект уничтожается сразу, память освобождается
2. Если есть циклические ссылки - такой простой механизм не работает.
Периодически запускается сборщик мусора, который пытается найти подвисшие кольца - и уничтожить их.
Немного упрощенно говоря, сборщик запускается если количество созданных объектов больше количества удаленных на пороговую величину (700 по умолчанию).
Подробности - в документации http://docs.python.org/library/gc.html?highlight=gc#module-gc
Офлайн
о_О спасибо.
Офлайн
Можно попробовать так:
res += [vals.pop( index ) for index, v in enumerate( reversed( vals ) ) if bool_func(v) ]
Отредактировано (Дек. 2, 2010 07:41:06)
Офлайн
Хмм. Я бы сделал дешево и сердито, зато понятно:
tmp = []
for v in vals:
if bool_func(v):
res.append(v)
else:
tmp.append(v)
vals = tmp
Офлайн
IsemК сожалению pop с enumerate совместно отказываются работать.
Можно попробовать так:Правда, операция pop может быть дорогая для больших списков, если извлекаемый элемент находится в начале списка. Однако, вполне возможно, что списки в питоне реализованы как деки, тогда удаление из середины списка наиболее времязатратно.res += [vals.pop( index ) for index, v in enumerate( reversed( vals ) ) if bool_func(v) ]
Офлайн
alexx11Ну, если уж так хочется извращений, то их есть у меня :):
К сожалению pop с enumerate совместно отказываются работать.
vals, res = reduce(lambda x,y:(x[bool_func(y)].append(y),x)[1], vals, [[],[]])
Офлайн
alexx11В виду того, что я не работаю с питоном версии ниже 3 в принципе, возможно это и так.
К сожалению pop с enumerate совместно отказываются работать.
EdЧто касается однопроходного варианта с циклом, то он, очевидно, самый простой и самый верный.
Хмм. Я бы сделал дешево и сердито, зато понятно:
Отредактировано (Дек. 3, 2010 03:20:23)
Офлайн