Python должен создавать новый список для каждой записи в myfunction1 () и назначать его для «большого списка».
В myfunction2 () вы передаете ссылку на глобальный «большой список», поэтому копирование не требуется.
Есть и другие, тонкие различия между ними. Передача этой ссылки оставляет глобальные данные открытыми для (возможно, нежелательного) вмешательства:
>>> biglist = [ 1,2,3,4,5,6,7,8,9 ]
>>> def myfunction3(mylist):
... mylist[2] = 99
...
>>> biglist
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> myfunction3(biglist)
>>> biglist
[1, 2, 99, 4, 5, 6, 7, 8, 9]
... тогда как объявление его в области действия означает, что оно создается каждый раз заново. Так, например:
>>> def myfunction4():
... mylist = [ 1,2,3,4,5 ]
... print mylist
... mylist[2] = 99
...
>>> myfunction4()
[1, 2, 3, 4, 5]
>>> myfunction4()
[1, 2, 3, 4, 5]
Каждый раз, когда вызывается функция, вы получаете свежую, чистую, незапятнанную копию списка, с которой можно поиграть.
Итак, как вы получаете лучшее из обоих миров? Попробуйте это:
>>> def myfunction5():
... mylist = biglist+[] # Make a private copy
... mylist[4] = 99
...
>>> biglist
[1, 2, 99, 4, 5, 6, 7, 8, 9]
>>> myfunction5()
>>> biglist
[1, 2, 99, 4, 5, 6, 7, 8, 9]
Вы видите, что список глобальных областей не изменился. Ваша новая функция, основанная на этом методе, будет:
def myfunction1a(number):
mylist = biglist+[] # Copy-safe version
print number*mylist
Как это соотносится с использованием ваших тестовых таймингов? Я знаю, что в этом случае вы на самом деле не изменяете «большой список» в своей функции, но это не плохая парадигма, чтобы привыкнуть к использованию, если вы должны были совместно использовать глобальные данные, и тот факт, что список создается только с нуля Один раз (а затем скопированный) может дать некоторые улучшения производительности.