Search code examples
listpython-3.xdictionarytuplesfilenames

Python3: Checking if a key word within a dictionary matches any part of a string


I'm having trouble converting my working code from lists to dictionaries. The basics of the code checks a file name for any keywords within the list.

But I'm having a tough time understanding dictionaries to convert it. I am trying to pull the name of each key and compare it to the file name like I did with lists and tuples. Here is a mock version of what i was doing.

fname = "../crazyfdsfd/fds/ss/rabbit.txt"
hollow = "SFV"
blank = "2008"
empty = "bender"

# things is list
things = ["sheep", "goat", "rabbit"]
# other is tuple
other = ("sheep", "goat", "rabbit")
#stuff is dictionary
stuff = {"sheep": 2, "goat": 5, "rabbit": 6}

try:
    print(type(things), "things")
    for i in things:
        if i in fname:
        hollow = str(i)
        print(hollow)
        if hollow == things[2]:
            print("PERFECT")
except:
    print("c-c-c-combo breaker")

print("\n \n")
try:
    print(type(other), "other")
    for i in other:
        if i in fname:
            blank = str(i)
            print(blank)
            if blank == other[2]:
                print("Yes. You. Can.")
except:
    print("THANKS OBAMA")

print("\n \n")
try:
    print(type(stuff), "stuff")
    for i in stuff:               # problem loop
        if i in fname:
            empty = str(i)
            print(empty)
            if empty == stuff[2]: # problem line
                print("Shut up and take my money!")
except:
    print("CURSE YOU ZOIDBERG!")

I am able to get a full run though the first two examples, but I cannot get the dictionary to run without its exception. The loop is not converting empty into stuff[2]'s value. Leaving money regrettably in fry's pocket. Let me know if my example isn't clear enough for what I am asking. The dictionary is just short cutting counting lists and adding files to other variables.


Solution

  • A dictionary is an unordered collection that maps keys to values. If you define stuff to be:

    stuff = {"sheep": 2, "goat": 5, "rabbit": 6}
    

    You can refer to its elements with:

    stuff['sheep'], stuff['goat'], stuff['rabbit']
    

    stuff[2] will result in a KeyError, because the key 2 is not found in your dictionary. You can't compare a string with the last or 3rd value of a dictionary, because the dictionary is not stored in an ordered sequence (the internal ordering is based on hashing). Use a list or tuple for an ordered sequence - if you need to compare to the last item.

    If you want to traverse a dictionary, you can use this as a template:

    for k, v in stuff.items():
        if k == 'rabbit':
            # do something  - k will be 'rabbit' and v will be 6
    

    If you want to check to check the keys in a dictionary to see if they match part of a string:

    for k in stuff.keys():
        if k in fname:
            print('found', k)
    

    Some other notes:

    The KeyError would be much easier to notice... if you took out your try/except blocks. Hiding python errors from end-users can be useful. Hiding that information from YOU is a bad idea - especially when you're debugging an initial pass at code.

    You can compare to the last item in a list or tuple with: if hollow == things[-1]: if that is what you're trying to do.

    In your last loop: empty == str(i) needs to be empty = str(i).