簡體   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