簡體   English   中英

如何更正錯誤“AttributeError: 'dict_keys' object has no attribute 'remove' '?

[英]How can I correct the error ' AttributeError: 'dict_keys' object has no attribute 'remove' '?

我正在嘗試使用 Dijkstra 算法編寫最短路徑查找器的代碼,但它似乎不起作用。 我不知道是什么問題。 我正在研究 Python 3.5 並關注此視頻

這是代碼:

graph = {
    'A': {'B': 10, 'D': 4, 'F': 10},
    'B': {'E': 5, 'J': 10, 'I': 17},
    'C': {'A': 4, 'D': 10, 'E': 16},
    'D': {'F': 12, 'G': 21},
    'E': {'G': 4},
    'F': {'E': 3},
    'G': {'J': 3},
    'H': {'G': 3, 'J': 3},
    'I': {},
    'J': {'I': 8},
}

def dijkstra(graph, start, end):
    D = {}
    P = {}
    for node in graph.keys():
        D[node]= -1
        P[node]=""
    D[start]=0
    unseen_nodes=graph.keys()
    while len(unseen_nodes) > 0:
        shortest=None
        node=' '
        for temp_node in unseen_nodes:
            if shortest==None:
                shortest = D[temp_node]
                node = temp_node
            elif D[temp_node]<shortest:
                    shortest=D[temp_node]
                    node=temp_node
        unseen_nodes.remove(node)
        for child_node, child_value in graph[node].items():
            if D[child_node] < D[node] + child_value:
                D[child_node] = D[node] + child_value
                P[child_node]=node
    path = []
    node = end
    while not (node==start):
        if path.count(node)==0:
            path.insert(0, node)
            node=P[node]
        else:
            break
    path.insert(0, start)
    return path

這是錯誤消息:

AttributeError: 'dict_keys' object has no attribute 'remove'

在Python 3中, dict.keys()返回一個沒有remove方法的dict_keys對象(字典視圖) ; 與Python 2不同, dict.keys()返回一個列表對象。

>>> graph = {'a': []}
>>> keys = graph.keys()
>>> keys
dict_keys(['a'])
>>> keys.remove('a')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'dict_keys' object has no attribute 'remove'

您可以使用list(..)來獲取密鑰列表:

>>> keys = list(graph)
>>> keys
['a']
>>> keys.remove('a')
>>> keys
[]

unseen_nodes = graph.keys()

unseen_nodes = list(graph)

在 Python 2 中, graph.keys()返回一個列表,其中定義了一個remove()方法( 參見此處的演示)。 graph.keys()是一個列表也意味着它是當前狀態下graph的鍵的新副本)。 在 Python 3 中,它返回一個 dict_keys object,它是字典鍵的視圖(這意味着無論何時修改graph ,視圖也會更改)。

由於 OP 想要創建定義remove()方法的字典鍵的新副本,因此另一種方法是創建一個set 換句話說,改變

unseen_nodes = graph.keys()

unseen_nodes = set(graph)

然后可以使用remove方法刪除節點。 一個示例將按如下方式工作。

graph = {'a': 2, 'b': 1}
unseen_nodes = set(graph)
unseen_nodes.remove('a')   # remove node `a`
unseen_nodes               # the remaining nodes: {'b'}

set 優於 list 的一個優點是它要快得多。 例如,從集合中刪除項目比從列表中刪除項目要快得多。 下面的測試表明,從集合中刪除項目比從列表中刪除項目快 1000 倍以上。

from timeit import timeit
setup = '''
import random
lst = list(range(100000))
st = set(range(100000))
keys = iter(random.sample(range(100000), 100000))
'''

t1 = timeit('lst.remove(next(keys))', setup, number=100000)
t2 = timeit('st.remove(next(keys))', setup, number=100000)
print(t1/t2)     # 1330.4911104284974

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM