Python—为什么我的列表没有在这个方法的范围之外被修改?我如何修改我的代码,使它是正确的?
我有以下方法:Python—为什么我的列表没有在这个方法的范围之外被修改?我如何修改我的代码,使它是正确的?,python,list,filter,scope,Python,List,Filter,Scope,我有以下方法: def instances(candidate, candidates): count = candidates.count(candidate) # Removing candidate from candidates. # list(filter(candidate.__ne__, candidates)) return {candidate: count} 其目的是查找列表中某个元素的实例数,从列表中删除这些实例,并返回表示该元素及其实例
def instances(candidate, candidates):
count = candidates.count(candidate)
# Removing candidate from candidates. #
list(filter(candidate.__ne__, candidates))
return {candidate: count}
其目的是查找列表中某个元素的实例数,从列表中删除这些实例,并返回表示该元素及其实例数的Key:Value
对
因此,如果我创建一个列表并调用该函数,它应该执行以下操作:
>>> someList = [1, 1, 1, 2, 3]
>>> print(instances(1, someList))
{1: 3}
>>> print(someList)
[2, 3]
while True:
try:
candidates.remove(candidate)
except ValueError:
# If there's no more candidate in candidates
# ValueError will be raised, in this case, we can stop removing
break
但是,对于最后一行,我得到的是:
>>> print(someList)
[1, 1, 1, 2, 3]
行列表(filter(candidate.\ne\uu,candidates))
返回我想要的正确列表,但它似乎只存在于函数的作用域中。如果我修改这一行,改为读取candidates=list(filter(candidate.\uu______,candidates))
,由于某种原因,candidates
被解释为函数范围内的局部变量。我不能简单地返回列表过滤器,因为我需要为程序的另一部分返回Key:Value
对
我发现非常奇怪的是,candidates
在这一行被解释为局部变量,而就在它上面,candidates
的引用被解释为函数的参数
有人能帮我理解为什么会这样吗?如果可能,建议与预期目的一致的解决方案?谢谢
您可以修改函数以返回两个结果:
def instances(candidate, candidates):
count = candidates.count(candidate)
return {candidate: count}, list(filter(candidate.__ne__, candidates))
运行时,请使用:
someList = [1, 1, 1, 2, 3]
res, someList = instances(1, someList)
print res
至于为什么它不起作用的解释,你可以找到一个详细的解释,我会自己尝试一下:
Python是“按值传递”,当您讨论传递int
或str
时,这是非常直接的。这就是说,当你传递“一个对象”时,它会变得更加混乱——你实际上传递的是对该对象引用的副本
这意味着对对象本身的任何更改都将在函数外部可见-,但是如果尝试更改引用本身-,它将不可见。还记得“复制”部分吗?您没有传递引用,但传递了该引用的副本-因此,将值重新分配给该引用副本将不可见
注释:另一个(好)选项是“更改指针后面的对象”-如他的回答中所示,使用切片 您可以修改函数以返回两个结果:
def instances(candidate, candidates):
count = candidates.count(candidate)
return {candidate: count}, list(filter(candidate.__ne__, candidates))
运行时,请使用:
someList = [1, 1, 1, 2, 3]
res, someList = instances(1, someList)
print res
至于为什么它不起作用的解释,你可以找到一个详细的解释,我会自己尝试一下:
Python是“按值传递”,当您讨论传递int
或str
时,这是非常直接的。这就是说,当你传递“一个对象”时,它会变得更加混乱——你实际上传递的是对该对象引用的副本
这意味着对对象本身的任何更改都将在函数外部可见-,但是如果尝试更改引用本身-,它将不可见。还记得“复制”部分吗?您没有传递引用,但传递了该引用的副本-因此,将值重新分配给该引用副本将不可见
注释:另一个(好)选项是“更改指针后面的对象”-如他的回答中所示,使用切片 过滤器(候选者。候选者)
不修改候选者
。它返回新的迭代器。并且list(过滤器(…)
返回新列表
试试这个
def instances(candidate, candidates):
count = candidates.count(candidate)
# Removing candidate from candidates.
for i in range(count)
candidates.remove(candidate)
return {candidate: count}
过滤器(候选者.\uu___,候选者)
不修改候选者
。它返回新的迭代器。并且list(过滤器(…)
返回新列表
试试这个
def instances(candidate, candidates):
count = candidates.count(candidate)
# Removing candidate from candidates.
for i in range(count)
candidates.remove(candidate)
return {candidate: count}
在这行中,候选变量被解释为局部变量,而在它上面,对候选变量的引用被解释为函数的参数,这真的很奇怪
蟒蛇。它有变量foo=bar
表示“使变量foo
指向bar
指向的任何位置”。重新指定变量只需重新定位指针。它不允许您更改指向给定值的“其他”变量。使用相同的方法传递参数:创建指向对象的新指针。因此,没有直接的支持
就地修改列表是通过切片语法完成的。你可以这样做:
candidates[:] = filter(candidate.__ne__, candidates)
在这行中,候选变量被解释为局部变量,而在它上面,对候选变量的引用被解释为函数的参数,这真的很奇怪
蟒蛇。它有变量foo=bar
表示“使变量foo
指向bar
指向的任何位置”。重新指定变量只需重新定位指针。它不允许您更改指向给定值的“其他”变量。使用相同的方法传递参数:创建指向对象的新指针。因此,没有直接的支持
就地修改列表是通过切片语法完成的。你可以这样做:
candidates[:] = filter(candidate.__ne__, candidates)
list(filter(candidate.\uu ne\uuu,candidates))
(特别是filter
)不修改列表候选者
,它只返回一个与候选者
不同的新筛选列表
就你而言,我建议如下:
>>> someList = [1, 1, 1, 2, 3]
>>> print(instances(1, someList))
{1: 3}
>>> print(someList)
[2, 3]
while True:
try:
candidates.remove(candidate)
except ValueError:
# If there's no more candidate in candidates
# ValueError will be raised, in this case, we can stop removing
break
list(filter(candidate.\uu ne\uuu,candidates))
(特别是filter
)不修改列表候选者
,它只返回一个与候选者
不同的新筛选列表
就你而言,我建议如下:
>>> someList = [1, 1, 1, 2, 3]
>>> print(instances(1, someList))
{1: 3}
>>> print(someList)
[2, 3]
while True:
try:
candidates.remove(candidate)
except ValueError:
# If there's no more candidate in candidates
# ValueError will be raised, in this case, we can stop removing
break
在这种情况下,您甚至不需要
list()
;切片作业需要任何时间。@kindall:谢谢,修复了。谢谢!第一个链接的url特别有用。在这种情况下,您甚至不需要list()
;切片分配将需要任何时间。@kindall:谢谢,fix