python赋值引用问题


关于python引用的问题,有p的是我要的结果。
有p这个中间变量后为什么结果不同,tire和p是怎么引用的,
有图最好了。

代码:


 def no_p():
    trie = {}
    word = 'foot'
    print('no_p', id(trie))
    for c in word:
        if c not in trie:
            trie[c] = {}
            print('no_p:', c, trie)
            print('no_p', id(trie))
        trie = trie[c]
        print('no_p:', id(trie))
    trie[''] = ''
    print('no_p:', trie)


def have_p():
    trie = {}
    p = trie
    word = 'foot'
    print('have_p:', id(trie), id(p))
    for c in word:
        if c not in p:
            p[c] = {}
            print('have_p:', c, trie)
            print('have_p:', id(trie), id(p))
        p = p[c]
        print('have_p:', id(trie), id(p))
    p[''] = ''
    print('have_p:', trie)


if __name__ == '__main__':
    no_p()
    have_p()

结果:
no_p 21667928
no_p: f {'f': {}}
no_p 21667928
no_p: 21680536
no_p: o {'o': {}}
no_p 21680536
no_p: 21667928
no_p: o {'o': {}}
no_p 21667928
no_p: 21680536
no_p: t {'t': {}}
no_p 21680536
no_p: 21667928
no_p: {'': ''}
have_p: 21667928 21667928
have_p: f {'f': {}}
have_p: 21667928 21667928
have_p: 21667928 21680536
have_p: o {'f': {'o': {}}}
have_p: 21667928 21680536
have_p: 21667928 21680336
have_p: o {'f': {'o': {'o': {}}}}
have_p: 21667928 21680336
have_p: 21667928 44964360
have_p: t {'f': {'o': {'o': {'t': {}}}}}
have_p: 21667928 44964360
have_p: 21667928 44964760
have_p: {'f': {'o': {'o': {'t': {'': ''}}}}}

引用 python 赋值

泡泡Ж忍者 10 years, 2 months ago

首先说明一下,由于个人的洁癖问题,我不认为Python里存在“变量”这种东西,存在的只是“名字”(name)。

在你的 no_p 的代码里,第一次 trie = trie[c] 之后, trie 这个名字现在指向 trie[c] 所指向的那个对象,同时你也丢失了对 trie 原来指向的那个字典的引用(而且由于现在没有任何名字指向它,你基本上已经不可能获得对它的引用了,它甚至可能会被GC掉)。代码这样跑下去,你的 trie 只会指向叶子节点(还是其它什么东西)。


 初始状态     +------+        trie = trie[c]后    +------+     +-------+
            | root |                            | root | --> | child |
            +------+                            +------+     +-------+
              ^                                   ^             ^
              |                                   |             |
              +- trie                             +- 丢失引用    +- trie

所以现在可以得出结论,就是你的 no_p 缺少对整个树的引用,这也是你在 have_p 里实现了的东西。


 初始状态     +------+          p = p[c]后        +------+     +-------+
            | root |                            | root | --> | child |
            +------+                            +------+     +-------+
              ^  ^                                ^             ^
             /    \                               |             |
         p -+      +- trie                        +- trie       +- p

不知道我说的够不够清楚。

枯萎的树海 answered 10 years, 2 months ago

Your Answer