Найти - Пользователи
Полная версия: Как код улучшить?
Начало » Python для новичков » Как код улучшить?
1 2 3
alexx11
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]]
Если v очень большой (10000 - маловато, скорее всего) - выгодней пройти одним циклом. Скорее всего случай не про вас.

А вообще здесь много не выгадаешь - в двух строчках почти нечего улучшать.
Но пережевывать, понемногу изменяя запись - можно бесконечно :)
alexx11
bool_func - лёгкая, а элементы v - это кортежи и могут быть большие. len(vals) не большой около двух тыщ.
Я больше всего боялся что сами кортежи начнут копироваться, а сейчас присмотрелся вроде нет, говоря языком си только указатели копируются. Такой положение вещей меня устраивает в любом варианте.

Офф топ. Вот понимать бы как в питоне память утилизируется, я на это опять же смотрю с точки зрения создания оптимального кода. Может есть где почитать про это?
Андрей Светлов
Если по простому - есть два этапа.
1. Когда счетчик ссылок становится равным 0 - объект уничтожается сразу, память освобождается
2. Если есть циклические ссылки - такой простой механизм не работает.
Периодически запускается сборщик мусора, который пытается найти подвисшие кольца - и уничтожить их.
Немного упрощенно говоря, сборщик запускается если количество созданных объектов больше количества удаленных на пороговую величину (700 по умолчанию).
Подробности - в документации http://docs.python.org/library/gc.html?highlight=gc#module-gc
alexx11
о_О спасибо.
Isem
Можно попробовать так:
res += [vals.pop( index ) for index, v in enumerate( reversed( vals ) ) if bool_func(v) ]
Правда, операция pop может быть дорогая для больших списков, если извлекаемый элемент находится в начале списка. Однако, вполне возможно, что списки в питоне реализованы как деки, тогда удаление из середины списка наиболее времязатратно.
Ed
Хмм. Я бы сделал дешево и сердито, зато понятно:
tmp = []
for v in vals:
if bool_func(v):
res.append(v)
else:
tmp.append(v)
vals = tmp
alexx11
Isem
Можно попробовать так:
res += [vals.pop( index ) for index, v in enumerate( reversed( vals ) ) if bool_func(v) ]
Правда, операция pop может быть дорогая для больших списков, если извлекаемый элемент находится в начале списка. Однако, вполне возможно, что списки в питоне реализованы как деки, тогда удаление из середины списка наиболее времязатратно.
К сожалению pop с enumerate совместно отказываются работать.
Ed уже второй человек говорит что лучше одним циклом пройти, придётся так и сделать =)
Ed
alexx11
К сожалению pop с enumerate совместно отказываются работать.
Ну, если уж так хочется извращений, то их есть у меня :):
vals, res = reduce(lambda x,y:(x[bool_func(y)].append(y),x)[1], vals, [[],[]])
Isem
alexx11
К сожалению pop с enumerate совместно отказываются работать.
В виду того, что я не работаю с питоном версии ниже 3 в принципе, возможно это и так.
Ed
Хмм. Я бы сделал дешево и сердито, зато понятно:
Что касается однопроходного варианта с циклом, то он, очевидно, самый простой и самый верный.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB