繁体   English   中英

Python-为什么我的列表未在此方法范围之外进行修改? 如何修改我的代码?

[英]Python - Why is my list not being modified outside the scope of this method? How do I modify my code so that it is?

我有以下方法:

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]

但是,对于最后一行,我得到的是:

>>> print(someList)
[1, 1, 1, 2, 3]

list(filter(candidate.__ne__, candidates))返回我想要的正确列表,但似乎它仅存在于函数的作用域内。 如果我修改此行以改为读取candidates = list(filter(candidate.__ne__, candidates)) ,由于某种原因, candidates将被解释为函数范围内的局部变量。 我不能简单地返回列表过滤器,因为我需要为程序的另一部分返回Key:Value对。

我发现在这行中将candidates解释为局部变量确实很奇怪,而在其上方,对candidates的引用被解释为函数的参数。

有人可以帮我了解为什么会这样吗? 如果可能,建议与预期目的一致的解决方案? 谢谢!

我发现在这行中将候选人解释为局部变量确实很奇怪,而在其上方,对候选人的引用被解释为函数的参数。

Python 没有引用 它具有变量。 foo = bar意思是“使变量foo指向任何bar指向的位置。” 重新分配变量只是重新放置了指针。 它不允许您更改指向给定值的“其他”变量。 使用相同的方法传递参数:创建指向该对象的新指针。 因此,不直接支持三星级编程

就地修改列表是通过切片语法完成的。 您可以执行以下操作:

candidates[:] = filter(candidate.__ne__, 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是“按值传递”,当您讨论传递intstr时,这很简单。 就是说,当您传递“对象”时,它变得更加混乱-您实际传递的是对该对象的引用副本

这意味着对对象本身的任何更改将在函数外部可见- 但是,如果您尝试更改引用本身-将不可见。 还记得“复制”部分吗? 您没有传递参考,而是传递了该参考的副本-因此将看不到给该参考的副本重新分配值!

评论 :另一个(好的)选择是“更改指针后面的对象”-正如Kevin通过使用切片在答案中所示!

filter(candidate.__ne__, candidates)不会修改candidates 它返回新的迭代器。 并且list(filter(...))返回新列表。

尝试这个

def instances(candidate, candidates):
count = candidates.count(candidate)

# Removing candidate from candidates.
for i in range(count)
    candidates.remove(candidate)
return {candidate: count}

list(filter(candidate.__ne__, candidates)) (特别是filter )不会修改列表中的candidates ,它只是返回一个不同于candidates的新过滤列表。

对于您的情况,我建议以下几点:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM