0

I have a specific problem in which I observe all the confusion of reference and dereference in python. I have a global structure wordhistory which I change on various levels inside a function addWordHistory:

wordhistory = dict()

def addWordHistory(words):
    global wordhistory
    current = wordhistory
    for word in words:
        if current is None:
            current = {word:[None,1]}    #1
        else:
            if word in current:
                current[word][1] += 1
            else:
                current[word] = [None,1]
    current = current[word][0]           #2

In line #1, I want to change the value behind the reference that has been assigned to the local variable current in line #2. This does not seem to work like this. Instead, I suspect that only the local variable is changed from a reference to a dictionary.

The below variant works, but I want to save the memory of all the empty leave dictionaries:

wordhistory = dict()

def addWordHistory(words):
    global wordhistory
    current = wordhistory
    for word in words:
        if word in current:
            current[word][1] += 1
        else:
            current[word] = [dict(),1]
        current = current[word][0]
7
  • 1
    line #1 never run. Also you can use collections.Counter to count the word occurrence in your list of words. Commented Feb 27, 2014 at 23:46
  • 1) line #1 runs, I have checked it. 2) it is a bit more complicated than that. Commented Feb 28, 2014 at 8:07
  • @user1850980 Are you sure the indentation of #2 is correct? Commented Feb 28, 2014 at 11:04
  • 1
    the only way #1 could run, is if current is None. Current is the same as wordhistory. So the only way for that line to run, would be if you set wordhistory to None, which would make no sense. If it runs, you're doing something more than this code shows. Commented Feb 28, 2014 at 11:12
  • Perhaps I should explain what I am doing: I am building a binary tree with a depth depending on the length of the history to be observed. The first child is None if the node is a leave and a dictionary to child nodes, if the node is not a leave. The second child is an integer that stores the count of sequence of words represented by the path from the root to the curent node. Current is supposed to be a pointer that goes down one level fo each of the input words counted. Commented Feb 28, 2014 at 12:18

1 Answer 1

1

To be able to change an item of the current list, you need to store the reference to the list, not just to the item you need to change:

def addWordHistory(words):
    current = [wordhistory, 0]
    for word in words:
        if current[0] is None:
            current[0] = dict()
        children = current[0]
        if word in children:
            children[word][1] += 1
        else:
            children[word] = [None, 1]
        current = children[word]
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.