Для python3 мне изначально нужно было извлечь нечетные и четные позиции из списка и назначить их новым спискам, а затем очистить исходный список. Я думал, что на списки повлиял вызов функции через передачу по ссылке. Тестирование некоторых сценариев, это работает когда-то. Может кто-нибудь объяснить, как именно здесь работает python3?
Случай 1: пустой список заполняется строкой, как и ожидалось.
def func1(_in):
_in.append('abc')
mylist = list()
print(f"Before:\nmylist = {mylist}")
func1(mylist)
print(f"After:\nmylist = {mylist}")
Выходной случай 1:
Before:
mylist = []
After:
mylist = ['abc']
Случай 2: средний элемент списка заменен строкой, как и ожидалось.
def func2(_in):
_in[1] = 'abc'
mylist = list(range(3))
print(f"Before:\nmylist = {mylist}")
func2(mylist)
print(f"After:\nmylist = {mylist}")
Выходной случай 2:
Before:
mylist = [0, 1, 2]
After:
mylist = [0, 'abc', 2]
Случай 3: почему список не пуст после вызова функции?
def func3(_in):
_in = list()
mylist = list(range(3))
print(f"Before:\nmylist = {mylist}")
func3(mylist)
print(f"After:\nmylist = {mylist}")
Выходной случай 3:
Before:
mylist = [0, 1, 2]
After:
mylist = [0, 1, 2]
Случай 4: работает точно так, как ожидалось, но обратите внимание, что я вернул все три списка из функции.
def func4_with_ret(_src, _dest1, _dest2):
_dest1 = [val for val in _src[0:len(_src):2]]
_dest2 = [val for val in _src[1:len(_src):2]]
_src = list()
return _src, _dest1, _dest2
source = list(range(6))
evens, odds = list(), list()
print(f"Before function call:\nsource = {source}\nevens = {evens}\nodds = {odds}")
source, evens, odds = func4_with_ret(source, evens, odds)
print(f"\nAfter function call:\nsource = {source}\nevens = {evens}\nodds = {odds}")
Выходной случай 4:
Before function call:
source = [0, 1, 2, 3, 4, 5]
evens = []
odds = []
After function call:
source = []
evens = [0, 2, 4]
odds = [1, 3, 5]
Случай 5: почему никакое влияние на переменные вне функции, если я не возвращаюсь явно из вызова функции?
def func5_no_ret(_src, _dest1, _dest2):
_dest1 = [val for val in _src[0:len(_src):2]]
_dest2 = [val for val in _src[1:len(_src):2]]
_src = list()
source = list(range(6))
evens, odds = list(), list()
print(f"Before function call:\nsource = {source}\nevens = {evens}\nodds = {odds}")
func5_no_ret(source, evens, odds)
print(f"\nAfter function call:\nsource = {source}\nevens = {evens}\nodds = {odds}")
Выходной случай 5:
Before function call:
source = [0, 1, 2, 3, 4, 5]
evens = []
odds = []
After function call:
source = [0, 1, 2, 3, 4, 5]
evens = []
odds = []
Спасибо.
_in = list()
,_in
будет локальным (только в функции), вы создаете новый объект_in
. Если вы используете_in.clear()
, изменение будет глобальным и приведет к пустому списку. Точно так же_dest1
— это новое назначение (только локальное), а_dest1.extend([val for val in _src[0:len(_src):2]])
— это глобальный вариант. - person Thymen   schedule 29.01.2021list
, полученное в_in
, может не быть глобальным, даже если оно есть в примере кода)._in
сам по себе всегда является локальным в этом коде, но иногда он использует псевдоним для объекта, предоставленного вызывающей стороной (когда функция введена, это всегда верно), но он может быть повторно привязан к другому объекту (который может или не может быть вновь созданным;_in = some_global
назначит его тому же объекту, что и глобальный, но_in
останется локальным). Настоящая проблема заключается в мутации и повторной привязке/переназначении, не связанной с областью действия. - person ShadowRanger   schedule 29.01.2021_in.append
или_in[i] = x
, или они не изменяют объект списка,_in = list()
. Это просто присваивание, а присваивание никогда не изменяется. Проверьте: nedbatchelder.com/text/names.html - person juanpa.arrivillaga   schedule 29.01.2021