Using a list to find occurrences in a nested dictionary

Question:

So I have a nested dictionary:

{1: {'letter': 'A', 'is_vowel': True, 'point_value': 1},
2: {'letter': 'B', 'is_vowel': False, 'point_value': 3},
3: {'letter': 'C', 'is_vowel': False, 'point_value': 3},
4: {'letter': 'D', 'is_vowel': False, 'point_value': 2},
5: {'letter': 'E', 'is_vowel': True, 'point_value': 1},
6: {'letter': 'F', 'is_vowel': False, 'point_value': 4},
7: {'letter': 'G', 'is_vowel': False, 'point_value': 2},
8: {'letter': 'H', 'is_vowel': False, 'point_value': 4},
9: {'letter': 'I', 'is_vowel': True, 'point_value': 1},
10: {'letter': 'J', 'is_vowel': False, 'point_value': 8},
11: {'letter': 'K', 'is_vowel': False, 'point_value': 5},
12: {'letter': 'L', 'is_vowel': False, 'point_value': 1},
13: {'letter': 'M', 'is_vowel': False, 'point_value': 3},
14: {'letter': 'N', 'is_vowel': False, 'point_value': 1},
15: {'letter': 'O', 'is_vowel': True, 'point_value': 1},
16: {'letter': 'P', 'is_vowel': False, 'point_value': 3},
17: {'letter': 'Q', 'is_vowel': False, 'point_value': 10},
18: {'letter': 'R', 'is_vowel': False, 'point_value': 1},
19: {'letter': 'S', 'is_vowel': False, 'point_value': 1},
20: {'letter': 'T', 'is_vowel': False, 'point_value': 1},
21: {'letter': 'U', 'is_vowel': True, 'point_value': 1},
22: {'letter': 'V', 'is_vowel': False, 'point_value': 4},
23: {'letter': 'W', 'is_vowel': False, 'point_value': 4},
24: {'letter': 'X', 'is_vowel': False, 'point_value': 8},
25: {'letter': 'Y', 'is_vowel': False, 'point_value': 4},
26: {'letter': 'Z', 'is_vowel': False, 'point_value': 10}
}

I would like to use a list of random letters for example:

['I', 'O', 'N', 'V', 'X', 'V', 'H', 'L', 'O', 'N', 'P', 'A', 'L', 'R', 'G', 'G', 'N', 'K', 'W', 'L', 'I', 'P', 'R', 'X', 'R', 'A']

and make a NEW list that contains the corresponding point_value listed in the dictionary for each letter.

What’s the best way to go about this?

I tried making a function that takes the list and dictionary as arguments:

def point_value_rand_letters(list, dic):
    point_values = []
    for letter in list:
        value = {i for i in dic if dic[i]['letter']==letter}
        point_values.append(value)
    print(point_values)
    return point_values

But I think I’m misunderstanding the code I used to find the value:

{i for i in dic if dic[i]['letter']==letter}

doing this gives me a list of the keys but as a list of sets (this is just an example and these don’t correspond to the example list I made above):

[{12}, {19}, {20}, {24}, {23}, {24}, {15}, {8}, {21}, {7}, {19}, {14}, {9}, {15}, {9}, {6}, {19}, {9}, {22}, {17}, {11}, {15}, {19}, {2}, {4}]

Maybe I need to convert the sets to an int somehow? and then I can use those as keys to find ‘point_value’? Or maybe I’m being too complicated and approaching this wrong…

Thanks!

Asked By: user2994120

||

Answers:

Iterate over each element in the list given (i.e. letters), find its key using ord(), get the key’s corresponding value and append that to the new list:

def point_value_rand_letters(letter_list, dict_):
    point_values = []
    
    for letter in letter_list:
        value = dict_[ord(letter) - 64]['point_value']
        point_values.append(value)
    
    return point_values

Try it:

l = [
    'I', 'O', 'N', 'V', 'X', 'V', 'H', 'L', 'O',
    'N', 'P', 'A', 'L', 'R', 'G', 'G', 'N', 'K',
    'W', 'L', 'I', 'P', 'R', 'X', 'R', 'A'
]

print(point_values_rand_letters(l, your_dict))
# [
#     1, 1, 1, 4, 8, 4, 4, 1, 1,
#     1, 3, 1, 1, 1, 2, 2, 1, 5,
#     4, 1, 1, 3, 1, 8, 1, 1
# ]
Answered By: InSync

There are countless ways to achieve this. But here is one example.

Create a function that returns the correct point value for a single letter that you pass in as a parameter.

Then you can use list comprehension to get the correct point value for each letter in the list.

a = {1: {'letter': 'A', 'is_vowel': True, 'point_value': 1},
2: {'letter': 'B', 'is_vowel': False, 'point_value': 3},
3: {'letter': 'C', 'is_vowel': False, 'point_value': 3},
4: {'letter': 'D', 'is_vowel': False, 'point_value': 2},
5: {'letter': 'E', 'is_vowel': True, 'point_value': 1},
6: {'letter': 'F', 'is_vowel': False, 'point_value': 4},
7: {'letter': 'G', 'is_vowel': False, 'point_value': 2},
8: {'letter': 'H', 'is_vowel': False, 'point_value': 4},
9: {'letter': 'I', 'is_vowel': True, 'point_value': 1},
10: {'letter': 'J', 'is_vowel': False, 'point_value': 8},
11: {'letter': 'K', 'is_vowel': False, 'point_value': 5},
12: {'letter': 'L', 'is_vowel': False, 'point_value': 1},
13: {'letter': 'M', 'is_vowel': False, 'point_value': 3},
14: {'letter': 'N', 'is_vowel': False, 'point_value': 1},
15: {'letter': 'O', 'is_vowel': True, 'point_value': 1},
16: {'letter': 'P', 'is_vowel': False, 'point_value': 3},
17: {'letter': 'Q', 'is_vowel': False, 'point_value': 10},
18: {'letter': 'R', 'is_vowel': False, 'point_value': 1},
19: {'letter': 'S', 'is_vowel': False, 'point_value': 1},
20: {'letter': 'T', 'is_vowel': False, 'point_value': 1},
21: {'letter': 'U', 'is_vowel': True, 'point_value': 1},
22: {'letter': 'V', 'is_vowel': False, 'point_value': 4},
23: {'letter': 'W', 'is_vowel': False, 'point_value': 4},
24: {'letter': 'X', 'is_vowel': False, 'point_value': 8},
25: {'letter': 'Y', 'is_vowel': False, 'point_value': 4},
26: {'letter': 'Z', 'is_vowel': False, 'point_value': 10}
}


b = ['I', 'O', 'N', 'V', 'X', 'V', 'H', 'L', 'O', 'N', 'P', 'A', 'L', 'R', 'G', 'G', 'N', 'K', 'W', 'L', 'I', 'P', 'R', 'X', 'R', 'A']

def point_value(x, a):
    for v in a.values():
        if v["letter"] == x:
            return v["point_value"]

c = [point_value(x, a) for x in b]
print(c)
Answered By: Alexander

Not sure if its the cleanest way, but it works.

    nested_dict=   {1: {'letter': 'A', 'is_vowel': True, 'point_value': 1},
                2: {'letter': 'B', 'is_vowel': False, 'point_value': 3},
                3: {'letter': 'C', 'is_vowel': False, 'point_value': 3},
                4: {'letter': 'D', 'is_vowel': False, 'point_value': 2},
                5: {'letter': 'E', 'is_vowel': True, 'point_value': 1},
                6: {'letter': 'F', 'is_vowel': False, 'point_value': 4},
                7: {'letter': 'G', 'is_vowel': False, 'point_value': 2},
                8: {'letter': 'H', 'is_vowel': False, 'point_value': 4},
                9: {'letter': 'I', 'is_vowel': True, 'point_value': 1},
                10: {'letter': 'J', 'is_vowel': False, 'point_value': 8},
                11: {'letter': 'K', 'is_vowel': False, 'point_value': 5},
                12: {'letter': 'L', 'is_vowel': False, 'point_value': 1},
                13: {'letter': 'M', 'is_vowel': False, 'point_value': 3},
                14: {'letter': 'N', 'is_vowel': False, 'point_value': 1},
                15: {'letter': 'O', 'is_vowel': True, 'point_value': 1},
                16: {'letter': 'P', 'is_vowel': False, 'point_value': 3},
                17: {'letter': 'Q', 'is_vowel': False, 'point_value': 10},
                18: {'letter': 'R', 'is_vowel': False, 'point_value': 1},
                19: {'letter': 'S', 'is_vowel': False, 'point_value': 1},
                20: {'letter': 'T', 'is_vowel': False, 'point_value': 1},
                21: {'letter': 'U', 'is_vowel': True, 'point_value': 1},
                22: {'letter': 'V', 'is_vowel': False, 'point_value': 4},
                23: {'letter': 'W', 'is_vowel': False, 'point_value': 4},
                24: {'letter': 'X', 'is_vowel': False, 'point_value': 8},
                25: {'letter': 'Y', 'is_vowel': False, 'point_value': 4},
                26: {'letter': 'Z', 'is_vowel': False, 'point_value': 10}
                }
letter_list =['I', 'O', 'N', 'V', 'X', 'V', 'H', 'L', 'O', 'N', 'P', 'A', 'L', 'R', 'G', 'G', 'N', 'K', 'W', 'L', 'I', 'P', 'R', 'X', 'R', 'A']

dict_length= len(nested_dict)
point_list=[]

for letter in letter_list:

    for num in range(1,dict_length+1):   # since Key,Value is 1to26
        if (nested_dict[num]["letter"])==letter:
            current_point_value= nested_dict[num]["point_value"]
            point_list.append(current_point_value)

print(point_list)
Answered By: Agnivesh Sp

The most efficient way to do this is to have a complementary dictionary which avoids the need for continual searching of the original dictionary. For example:

mdict = {1: {'letter': 'A', 'is_vowel': True, 'point_value': 1},
         2: {'letter': 'B', 'is_vowel': False, 'point_value': 3},
         3: {'letter': 'C', 'is_vowel': False, 'point_value': 3},
         4: {'letter': 'D', 'is_vowel': False, 'point_value': 2},
         5: {'letter': 'E', 'is_vowel': True, 'point_value': 1},
         6: {'letter': 'F', 'is_vowel': False, 'point_value': 4},
         7: {'letter': 'G', 'is_vowel': False, 'point_value': 2},
         8: {'letter': 'H', 'is_vowel': False, 'point_value': 4},
         9: {'letter': 'I', 'is_vowel': True, 'point_value': 1},
         10: {'letter': 'J', 'is_vowel': False, 'point_value': 8},
         11: {'letter': 'K', 'is_vowel': False, 'point_value': 5},
         12: {'letter': 'L', 'is_vowel': False, 'point_value': 1},
         13: {'letter': 'M', 'is_vowel': False, 'point_value': 3},
         14: {'letter': 'N', 'is_vowel': False, 'point_value': 1},
         15: {'letter': 'O', 'is_vowel': True, 'point_value': 1},
         16: {'letter': 'P', 'is_vowel': False, 'point_value': 3},
         17: {'letter': 'Q', 'is_vowel': False, 'point_value': 10},
         18: {'letter': 'R', 'is_vowel': False, 'point_value': 1},
         19: {'letter': 'S', 'is_vowel': False, 'point_value': 1},
         20: {'letter': 'T', 'is_vowel': False, 'point_value': 1},
         21: {'letter': 'U', 'is_vowel': True, 'point_value': 1},
         22: {'letter': 'V', 'is_vowel': False, 'point_value': 4},
         23: {'letter': 'W', 'is_vowel': False, 'point_value': 4},
         24: {'letter': 'X', 'is_vowel': False, 'point_value': 8},
         25: {'letter': 'Y', 'is_vowel': False, 'point_value': 4},
         26: {'letter': 'Z', 'is_vowel': False, 'point_value': 10}
         }

cdict = {d['letter']: d['point_value'] for d in mdict.values()}

lol = ['I', 'O', 'N', 'V', 'X', 'V', 'H', 'L', 'O', 'N', 'P', 'A', 'L',
       'R', 'G', 'G', 'N', 'K', 'W', 'L', 'I', 'P', 'R', 'X', 'R', 'A']

output = [cdict[c] for c in lol]

print(output)

Output:

[1, 1, 1, 4, 8, 4, 4, 1, 1, 1, 3, 1, 1, 1, 2, 2, 1, 5, 4, 1, 1, 3, 1, 8, 1, 1]
Answered By: DarkKnight

I also do some experiment and it works fine.

a = {1: {'letter': 'A', 'is_vowel': True, 'point_value': 1},
     2: {'letter': 'B', 'is_vowel': False, 'point_value': 3},
     3: {'letter': 'C', 'is_vowel': False, 'point_value': 3},
     4: {'letter': 'D', 'is_vowel': False, 'point_value': 2},
     5: {'letter': 'E', 'is_vowel': True, 'point_value': 1},
     6: {'letter': 'F', 'is_vowel': False, 'point_value': 4},
     7: {'letter': 'G', 'is_vowel': False, 'point_value': 2},
     8: {'letter': 'H', 'is_vowel': False, 'point_value': 4},
     9: {'letter': 'I', 'is_vowel': True, 'point_value': 1},
     10: {'letter': 'J', 'is_vowel': False, 'point_value': 8},
     11: {'letter': 'K', 'is_vowel': False, 'point_value': 5},
     12: {'letter': 'L', 'is_vowel': False, 'point_value': 1},
     13: {'letter': 'M', 'is_vowel': False, 'point_value': 3},
     14: {'letter': 'N', 'is_vowel': False, 'point_value': 1},
     15: {'letter': 'O', 'is_vowel': True, 'point_value': 1},
     16: {'letter': 'P', 'is_vowel': False, 'point_value': 3},
     17: {'letter': 'Q', 'is_vowel': False, 'point_value': 10},
     18: {'letter': 'R', 'is_vowel': False, 'point_value': 1},
     19: {'letter': 'S', 'is_vowel': False, 'point_value': 1},
     20: {'letter': 'T', 'is_vowel': False, 'point_value': 1},
     21: {'letter': 'U', 'is_vowel': True, 'point_value': 1},
     22: {'letter': 'V', 'is_vowel': False, 'point_value': 4},
     23: {'letter': 'W', 'is_vowel': False, 'point_value': 4},
     24: {'letter': 'X', 'is_vowel': False, 'point_value': 8},
     25: {'letter': 'Y', 'is_vowel': False, 'point_value': 4},
     26: {'letter': 'Z', 'is_vowel': False, 'point_value': 10}
     }

B = ['I', 'O', 'N', 'V', 'X', 'V', 'H', 'L', 'O', 'N', 'P', 'A', 'L', 'R', 'G', 'G', 'N', 'K', 'W', 'L', 'I', 'P', 'R',
     'X', 'R', 'A']

def point_value_rand_letters(B, a):
    point_values = []
    for letter in B:
         for x,y in a.items():
               if y['letter']==letter:
                    z = y['point_value']
                    point_values.append(z)
                    break
    return point_values

print(point_value_rand_letters(B, a))

Output: [1, 1, 1, 4, 8, 4, 4, 1, 1, 1, 3, 1, 1, 1, 2, 2, 1, 5, 4, 1, 1, 3, 1, 8, 1, 1]
Answered By: Nitiz
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.