Уведомления

Группа в Telegram: @pythonsu

#1 Ноя. 9, 2012 11:59:22

sergeek
Зарегистрирован: 2012-06-26
Сообщения: 470
Репутация: +  43  -
Профиль   Отправить e-mail  

Рекурсии и циклы

4kpt
производит опреедленные действия
тут нить обрывается(как событие может производить действия? вне функции??), и понять чем примечательна рекурсия в хуках невозможно.
Рекурсия плоха тем (как уже заметили), что самовызов функции серьезно нагружает машину.
проведем эксперимент с теми же вложенными списками:
пример который я уже приводил
f = lambda ls: reduce(lambda res, x: res+[x] if not isinstance(x,list) else res + f(x),ls,[])
можно оптимизировать, сократив вдвое количество вызовов функций и привести в более читабельный вид
def flatten(src_ls):
    res = []
    def make_flat(ls):
        for elt in ls:
            make_flat(elt) if (isinstance(elt,list)) else res.append(elt)
    make_flat(src_ls)
    return res

вариант с циклом
def hardcore(ls):
    res = []
    nested_elements = []
    positions = []
    for elt in ls:
        if isinstance(elt,list):
            nested_elements.append(elt)
        else:
            res.append(elt)
        idx = None
        offset = 0
        while nested_elements:
            nested_ls = nested_elements.pop()
            if positions:
                idx = positions.pop()
            got_nested = False 
            for nested_elt in nested_ls:
                if isinstance(nested_elt, list):
                    nested_elements.append(nested_elt)
                    positions.append(len(res)-offset)
                    got_nested = True
                else:
                    if got_nested:
                        offset += 1 
                    if idx:
                        res.insert(idx,nested_elt)
                        idx += 1
                    else:
                        res.append(nested_elt)
    return res

замеряем
%%timeit
f([1,[2,3,4,[5,[6],7,8],9],10,11,[12,[13]]])
100000 loops, best of 3: 8.07 us per loop
%%timeit
flatten([1,[2,3,4,[5,[6],7,8],9],10,11,[12,[13]]])
100000 loops, best of 3: 5.48 us per loop
%%timeit
hardcore([1,[2,3,4,[5,[6],7,8],9],10,11,[12,[13]]])
100000 loops, best of 3: 8.38 us per loop
На разработку первого варианта у меня ушло 5 минут, второго 2 минуты, третьего около часа. Как видно, помимо нехилого оверхеда вариант с циклом к тому же тормознее и жруч на память скорей всего. Так что профит рекурсии всеобъемлющ

Офлайн

#2 Ноя. 9, 2012 12:07:09

Singularity
Зарегистрирован: 2011-07-28
Сообщения: 1387
Репутация: +  75  -
Профиль   Отправить e-mail  

Рекурсии и циклы

4kpt
серьезно нагружает машину
А какие у вас характеристики компютера?

Офлайн

#3 Ноя. 9, 2012 12:14:55

odnochlen
Зарегистрирован: 2012-06-28
Сообщения: 794
Репутация: +  14  -
Профиль   Отправить e-mail  

Рекурсии и циклы

Singularity, под “серьезно нагружает” имелось в виду относительно цикла.

Офлайн

#4 Ноя. 9, 2012 13:12:42

adray
Зарегистрирован: 2012-09-15
Сообщения: 123
Репутация: +  18  -
Профиль   Отправить e-mail  

Рекурсии и циклы

sergeek
Как видно, помимо нехилого оверхеда вариант с циклом к тому же тормознее и жруч на память скорей всего. Так что профит рекурсии всеобъемлющ

Это зависит от ситуации.
Вот так не стоит делать:
def recur(n):
...   if not n == 0:
...     hardwork()
...     recur(n - 1)

норм:
def loop(n):
     for i in range(n):
          hardwork()

>>> timeit.timeit('req(10)','from __main__ import req')
10.308371383998747
timeit.timeit('loop(10)','from __main__ import loop')
6.014963355999498

sergeek
%%timeit
Как?! IronPython вроде так умеет, как запилить на обычном, может какой декоратор есть из библиотеки?

Офлайн

#5 Ноя. 9, 2012 13:55:41

sergeek
Зарегистрирован: 2012-06-26
Сообщения: 470
Репутация: +  43  -
Профиль   Отправить e-mail  

Рекурсии и циклы

adray
я ведь писал выше, что рекурсия эта полезна для обработки данных с рекурсивным устройством. Для плоских структур конечно же лучше применить цикл.
%%timeit
это просто magic function из IPython шелла

Офлайн

#6 Ноя. 9, 2012 14:34:20

sergeek
Зарегистрирован: 2012-06-26
Сообщения: 470
Репутация: +  43  -
Профиль   Отправить e-mail  

Рекурсии и циклы

adray
Как?! IronPython вроде так умеет, как запилить на обычном, может какой декоратор есть из библиотеки?
Ок, понял вы видимо считаете IronPython это и есть IPython, но это не так. А зачем оно надо? Стандартный шелл расширяем, его и расширили в IPython, если так надо именно в обычном - можете посмотреть в исходниках как оно делается

Офлайн

#7 Ноя. 9, 2012 23:20:02

4kpt
От: Харьков
Зарегистрирован: 2010-11-03
Сообщения: 998
Репутация: +  63  -
Профиль   Отправить e-mail  

Рекурсии и циклы

“как событие может производить действия? вне функции??”
Не придерайся к словам. Я имел ввиду, что вызывается, например, дополнительное графическое окно для ввода или выбора данных. Потом это окно (блин на событие из окна) вешается эта же фукция (вызов функции), но уже повторно обрабатывается с новым значеним параметра вызова. Делается это что-бы не писать на обрабоки событий отдельных функций… Получаестя (формально) рекурсия.



Отредактировано 4kpt (Ноя. 10, 2012 01:47:48)

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version