为什么这段代码会失败?在for循环中将变量分配给自身列表
Why does this code fail? assigning variable to list of itself in for loop
a = 'hello'
b = None
c = None
for x in [a, b, c]:
if isinstance(x, (basestring, dict, int, float)) or x is None:
x = [x]
a
returns'hello'
,但预计 ['hello']
。但是,这有效:
a = 'hello'
a = [a]
a
returns ['hello']
.
让我们一次完成这一行;
a = 'hello' # assigns 'hello' to a.
b = None # etc...
c = None
for x in [a, b, c]: # Creates list from the values in 'a' 'b' and 'c', then iterates over them.
# This if statement is always True. x is always either a string, or None.
if isinstance(x, (basestring, dict, int, float)) or x is None:
x = [x] # On the first iteration, sets variable to the expected ['hello']
# After that though - it replaces it with [None]
a # = 'hello' - you have not assigned anything to the variable except on the first line.
唯一设置为 ['hello']
的变量是 x
,它很快被 None
覆盖。如果您将 if 检查更改为排除 or x is None
并分配给 a
而不是 x
,您将获得所需的结果。
还值得注意的是,列表 [a, b, c]
是在您启动 for 循环时创建的。在 for 循环中更改 a
b
或 c
将无效 - 列表已经创建。
要做到这一点,首先您必须了解您有两个不同的引用,a 和 x(针对每个元素),以及列表 [a,b,c] 的引用,仅在 for 循环中使用,再也不会了。
为了实现你的目标,你可以这样做:
a = 'hello'
b = None
c = None
lst = [a, b, c] #here I create a reference for a list containing the three references above
for i,x in enumerate(lst):
if isinstance(x, (str,dict, int, float)) or x is None: #here I used str instead basestring
lst[i] = [x]
print(lst[0]) #here I print the reference inside the list, that's why the value is now showed modified
['hello']
但正如我所说,如果您执行 print(a) 它将再次显示:
'hello' #here i printed the value of the variable a, wich has no modification
因为你从来没有用它做过任何事情。
看看这个问题,了解更多关于参考文献的知识How do I pass a variable by reference?
其他答案都很棒。我认为,概括地说,列表元素是 immutable/hashable 所以 for 循环 returns 是一个副本,而不是对原始对象的引用。我早该发现这一点,但教我编码太久没睡觉!
我最终使用了这个:
def lst(x):
if isinstance(x, (basestring, dict, int, float)) or x is None:
x = [x]
return x
[a, b, c] = map(lst, [a, b, c])
a = 'hello'
b = None
c = None
for x in [a, b, c]:
if isinstance(x, (basestring, dict, int, float)) or x is None:
x = [x]
a
returns'hello'
,但预计 ['hello']
。但是,这有效:
a = 'hello'
a = [a]
a
returns ['hello']
.
让我们一次完成这一行;
a = 'hello' # assigns 'hello' to a.
b = None # etc...
c = None
for x in [a, b, c]: # Creates list from the values in 'a' 'b' and 'c', then iterates over them.
# This if statement is always True. x is always either a string, or None.
if isinstance(x, (basestring, dict, int, float)) or x is None:
x = [x] # On the first iteration, sets variable to the expected ['hello']
# After that though - it replaces it with [None]
a # = 'hello' - you have not assigned anything to the variable except on the first line.
唯一设置为 ['hello']
的变量是 x
,它很快被 None
覆盖。如果您将 if 检查更改为排除 or x is None
并分配给 a
而不是 x
,您将获得所需的结果。
还值得注意的是,列表 [a, b, c]
是在您启动 for 循环时创建的。在 for 循环中更改 a
b
或 c
将无效 - 列表已经创建。
要做到这一点,首先您必须了解您有两个不同的引用,a 和 x(针对每个元素),以及列表 [a,b,c] 的引用,仅在 for 循环中使用,再也不会了。
为了实现你的目标,你可以这样做:
a = 'hello'
b = None
c = None
lst = [a, b, c] #here I create a reference for a list containing the three references above
for i,x in enumerate(lst):
if isinstance(x, (str,dict, int, float)) or x is None: #here I used str instead basestring
lst[i] = [x]
print(lst[0]) #here I print the reference inside the list, that's why the value is now showed modified
['hello']
但正如我所说,如果您执行 print(a) 它将再次显示:
'hello' #here i printed the value of the variable a, wich has no modification
因为你从来没有用它做过任何事情。
看看这个问题,了解更多关于参考文献的知识How do I pass a variable by reference?
其他答案都很棒。我认为,概括地说,列表元素是 immutable/hashable 所以 for 循环 returns 是一个副本,而不是对原始对象的引用。我早该发现这一点,但教我编码太久没睡觉!
我最终使用了这个:
def lst(x):
if isinstance(x, (basestring, dict, int, float)) or x is None:
x = [x]
return x
[a, b, c] = map(lst, [a, b, c])