Найти - Пользователи
Полная версия: Список произвольной вложенности.
Начало » Python для новичков » Список произвольной вложенности.
1 2
Kon52
Есть функция:
def qwe(lst, new = []):
    for el in lst:
        qwe(el) if isinstance(el, list) else new.append(el)
    return new
При таком раскладе получаю:
a = qwe([1, [2, 3, [4, 5]]])
print a
[1, 2, 3, 4, 5]
НО:
def qwe(lst):
    new = []
    for el in lst:
        qwe(el) if isinstance(el, list) else new.append(el)
    return new
a = qwe([1, [2, 3, [4, 5]]])
print a
[1]
НО:
def qwe(lst):
    global new
    new = []
    for el in lst:
        qwe(el) if isinstance(el, list) else new.append(el)
    return new
a = qwe([1, [2, 3, [4, 5]]])
print a
[4, 5]

Почему так происходит?
Особенно между первым и вторым вариантом разница. Почему при таком же рекурсивном вызове функция с аргументом по умолчанию ведет себя отлично от функции, создающей пустой список в теле?
ayb
В первом варианте у Вас есть значение по умолчанию, которое фиксируется. Внутри функции Вы его изменяете и каждый новый вызов у функции новое значение по умолчанию. Во втором случае у Вас функция внутри цикла не связана ни с какой переменной. Т.е. она выполняеться но наверх результаты не дает.
Kon52
В последнем варианте, значит, каждый раз создаётся новая глобальная переменная new, поэтому в ней и остаются значения с последнего шага цикла.
Вроде разобрался, спасибо.
ayb
Ну вот смотрите :

>>> import inspect
>>> def some_func(a, b=[]):
...     b.append(a)
...     return b
... 
>>> inspect.getargspec(some_func)
ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=([],))

Вроде бы все ок, теперь вызовем функцию 2 раза
>>> some_func(1)
[1]
>>> some_func(2)
[1, 2]
>>> inspect.getargspec(some_func)
ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=([1, 2],))
>>> 

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

По второму примеру :

1. Внутри функции вы объявляете пустой список.
2. На первом шаге цикла for в этот список записывается значение 1.
3. На следующем шаге цикла срабатывает условие, функция начинает рекурсивно вызывать саму себя. При этом она возвращает значения, но Вы их никуда не записываете.
4. Функция заканчивает рекурсивно вызывать саму себя и возвращает список, который вы объявили в самом начале, и там только 1 элемент.

Ну а по третьему примеру все верно - функция каждый раз перезаписывает глобальную переменную.

PS : вообще объявлять функцию вот так функцию как у Вас в первом примере очень херовая практика.
Kon52
Очень подробно,но не стоило, я после первого ответа врубился.
Ещё раз благодарю


ayb
PS : вообще объявлять функцию вот так функцию как у Вас в первом примере очень херовая практика.
Если честно, это найдено было в сети, а в чем именно её херовость?
ayb
Kon52
Если честно, это найдено было в сети, а в чем именно её херовость?

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

Просто мне кажется, что чел, писавший эту функцию, понимал что он делает и для чего..
4kpt_III
Я вот вижу global в коде и его принципиально не использую. И мне как-бы серенево, понимает его создатель, зачем нужен global или нет

P.S. Хотите писать код, который не будут заворачивать техлид или тимлид - не используйте такие конструкции. Ну и global в том числе.
Kon52
4kpt_III
P.S. Хотите писать код, который не будут заворачивать техлид или тимлид - не используйте такие конструкции. Ну и global в том числе.
Так мы с ayb и не global обсуждали вовсе..Про её использование я в курсе, это так, эксперимент был
Мы первый пример разбирали, в частности- использование изменяемых объектов как аргументов по умолчанию. Он сказал, что так, мол, нельзя делать, я вот и не понял, почему нельзя- то?
Stright
Когда-то примерно то же самое спрашивал
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