udoyen udoyen - 5 months ago 14
Python Question

python dictionary iteration usage error

Ok here is my code:

# create variables
direction = ('north', 'south', 'east', 'west', 'down', 'up', 'left', 'right', 'back')
verb = ('go', 'stop', 'kill', 'eat')
stop = ('the', 'in', 'of', 'from', 'at', 'it')
noun = ('door', 'bear', 'princess', 'cabinet')
number = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9')

def scan(word, *words): # '*words' lets you give a variable number of arguments to a function
words = word.split()
src = { direction : 'direction',
verb : 'verb',
stop : 'stop',
noun : 'noun',
number : 'number'
}
for k, v in src.items():
if words in k:
m = src.get(k)

print [(m, w) for w in words]

scan("I was going north and south")


Problem:


  • I am trying to assign the value of the
    dic(src)
    to
    variable m
    after running words through
    src
    to see if one of the content of
    words
    can be found in
    src
    .



My Error:

Traceback (most recent call last):
File "koko2.py", line 26, in <module>
scan("I was going north and south")
File "koko2.py", line 24, in scan
print [(m, w) for w in words if w in direction or verb or stop or noun or number]
UnboundLocalError: local variable 'm' referenced before assignment

Answer

You logic is all wrong, words is a list and a list could never be in your tuple of words so it m never gets defines. You need to check if the individual word was in the key/tuple. I would use a frozenset of words as keys instead for O(1) lookups:

def scan(s):  # '*words' lets you give a variable number of     arguments to a function
    words = s.lower().split()
    src = {frozenset(direction): 'direction',
       frozenset(verb): 'verb',
       frozenset(stop): 'stop',
       frozenset(noun): 'noun',
       frozenset(number): 'number'
       }
    for word in words:
        for k, v in src.items():
            if word in k:
                yield word, v
                break


for pair in scan("I was going north and south"):
    print(pair)

Which would give you:

('north', 'direction')
('south', 'direction')

Also if you want to pass a word or words using *args, use *words alone and iterate directly:

def scan(*words):  # '*words' lets you give a variable number of     arguments to a function
    src = {frozenset(direction): 'direction',
           frozenset(verb): 'verb',
           frozenset(stop): 'stop',
           frozenset(noun): 'noun',
           frozenset(number): 'number'
           }
    for word in words:
        for k, v in src.items():
            if word in k:
                yield word, v    
                break



for pair in scan("I", "was", "going", "north", "and", "south"):
    print(pair)
Comments