Уведомления

Группа в Telegram: @pythonsu

#1 Дек. 1, 2010 22:46:56

alexx11
От:
Зарегистрирован: 2010-05-13
Сообщения: 208
Репутация: +  0  -
Профиль   Отправить e-mail  

Как код улучшить?

res += [v for v in vals if bool_func(v)]
vals = [v for v in vals if not bool_func(v)]



Офлайн

#2 Дек. 1, 2010 23:35:27

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Как код улучшить?

а 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 - маловато, скорее всего) - выгодней пройти одним циклом. Скорее всего случай не про вас.

А вообще здесь много не выгадаешь - в двух строчках почти нечего улучшать.
Но пережевывать, понемногу изменяя запись - можно бесконечно :)



Офлайн

#3 Дек. 2, 2010 00:07:59

alexx11
От:
Зарегистрирован: 2010-05-13
Сообщения: 208
Репутация: +  0  -
Профиль   Отправить e-mail  

Как код улучшить?

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

Офф топ. Вот понимать бы как в питоне память утилизируется, я на это опять же смотрю с точки зрения создания оптимального кода. Может есть где почитать про это?



Офлайн

#4 Дек. 2, 2010 00:38:59

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Как код улучшить?

Если по простому - есть два этапа.
1. Когда счетчик ссылок становится равным 0 - объект уничтожается сразу, память освобождается
2. Если есть циклические ссылки - такой простой механизм не работает.
Периодически запускается сборщик мусора, который пытается найти подвисшие кольца - и уничтожить их.
Немного упрощенно говоря, сборщик запускается если количество созданных объектов больше количества удаленных на пороговую величину (700 по умолчанию).
Подробности - в документации http://docs.python.org/library/gc.html?highlight=gc#module-gc



Офлайн

#5 Дек. 2, 2010 00:57:34

alexx11
От:
Зарегистрирован: 2010-05-13
Сообщения: 208
Репутация: +  0  -
Профиль   Отправить e-mail  

Как код улучшить?

о_О спасибо.



Офлайн

#6 Дек. 2, 2010 06:20:29

Isem
От:
Зарегистрирован: 2010-08-27
Сообщения: 447
Репутация: +  7  -
Профиль   Отправить e-mail  

Как код улучшить?

Можно попробовать так:

res += [vals.pop( index ) for index, v in enumerate( reversed( vals ) ) if bool_func(v) ]
Правда, операция pop может быть дорогая для больших списков, если извлекаемый элемент находится в начале списка. Однако, вполне возможно, что списки в питоне реализованы как деки, тогда удаление из середины списка наиболее времязатратно.



Отредактировано (Дек. 2, 2010 07:41:06)

Офлайн

#7 Дек. 2, 2010 10:43:58

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

Как код улучшить?

Хмм. Я бы сделал дешево и сердито, зато понятно:

tmp = []
for v in vals:
if bool_func(v):
res.append(v)
else:
tmp.append(v)
vals = tmp



Офлайн

#8 Дек. 2, 2010 11:18:25

alexx11
От:
Зарегистрирован: 2010-05-13
Сообщения: 208
Репутация: +  0  -
Профиль   Отправить e-mail  

Как код улучшить?

Isem
Можно попробовать так:
res += [vals.pop( index ) for index, v in enumerate( reversed( vals ) ) if bool_func(v) ]
Правда, операция pop может быть дорогая для больших списков, если извлекаемый элемент находится в начале списка. Однако, вполне возможно, что списки в питоне реализованы как деки, тогда удаление из середины списка наиболее времязатратно.
К сожалению pop с enumerate совместно отказываются работать.
Ed уже второй человек говорит что лучше одним циклом пройти, придётся так и сделать =)



Офлайн

#9 Дек. 2, 2010 20:50:01

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

Как код улучшить?

alexx11
К сожалению pop с enumerate совместно отказываются работать.
Ну, если уж так хочется извращений, то их есть у меня :):
vals, res = reduce(lambda x,y:(x[bool_func(y)].append(y),x)[1], vals, [[],[]])



Офлайн

#10 Дек. 3, 2010 03:17:34

Isem
От:
Зарегистрирован: 2010-08-27
Сообщения: 447
Репутация: +  7  -
Профиль   Отправить e-mail  

Как код улучшить?

alexx11
К сожалению pop с enumerate совместно отказываются работать.
В виду того, что я не работаю с питоном версии ниже 3 в принципе, возможно это и так.
Ed
Хмм. Я бы сделал дешево и сердито, зато понятно:
Что касается однопроходного варианта с циклом, то он, очевидно, самый простой и самый верный.



Отредактировано (Дек. 3, 2010 03:20:23)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version