dharmista
dharmista

Reputation: 103

List comprehensions in python nested loops

scrabble_scores = [(1, "EAOINRTLSU"), (2, "DG"), (3, "BCMP"),
               (4, "FHVWY"), (5, "K"), (8, "JX"), (10, "QZ")]
def get_scrabble_scorer():
    print {x:y for x,z in scrabble_scores for y in z}
    pass

get_scrabble_scorer()

I expected an output :

[1:'E',1:'A,1:'O',1:'I'....]

such that score will be mapped to each alphabet in the word But i got the output :

{1: 'U', 2: 'G', 3: 'P', 4: 'Y', 5: 'K', 8: 'X', 10: 'Z'}

Help me

Upvotes: 2

Views: 136

Answers (4)

Mike Müller
Mike Müller

Reputation: 85612

If you do not insist on the keys being the numbers use:

>>> {y:x for x,z in scrabble_scores for y in z}
{'E': 1, 'M': 3, 'F': 4, 'Z': 10, 'G': 2, 'Q': 10, 'U': 1, 'R': 1, 'I': 1, 'C': 3, 'A': 1, 'K': 5, 'Y': 4, 'L': 1, 'B': 3, 'O': 1, 'D': 2, 'T': 1, 'W': 4, 'S': 1, 'X': 8, 'P': 3, 'H': 4, 'J': 8, 'V': 4, 'N': 1}

You can use it to calculate the score of a word:

>>> score_mapping = {y:x for x,z in scrabble_scores for y in z}

>>> word = 'Hello'
>>> sum(score_mapping[letter.upper()] for letter in word)
8

Upvotes: 0

LaPriWa
LaPriWa

Reputation: 1803

You could change the line with the print command to:

print [{x:y} for x,z in scrabble_scores for y in z]

Then the output will be:

[{1: 'E'}, {1: 'A'}, {1: 'O'}, {1: 'I'}...

Upvotes: 1

Burhan Khalid
Burhan Khalid

Reputation: 174748

You need to switch the dictionary, so the keys are the letters and the values are the scores. Dictionaries in Python cannot have duplicate keys.

This is also how you will calculate the score of a word, by looking up each letter (not by looking up each number).

>>> {letter:score for score,letters in scrabble_scores for letter in letters}
{'A': 1, 'C': 3, 'B': 3, 'E': 1, 'D': 2, 'G': 2, 'F': 4, 'I': 1, 'H': 4, 'K': 5,
 'J': 8, 'M': 3, 'L': 1, 'O': 1, 'N': 1, 'Q': 10, 'P': 3, 'S': 1, 'R': 1, 'U': 1
, 'T': 1, 'W': 4, 'V': 4, 'Y': 4, 'X': 8, 'Z': 10}

Here is how you would use the above mapping:

>>> word = 'hello'
>>> score = sum(lookup.get(i.upper(),0) for i in word)
>>> score
8

Upvotes: 0

The Obscure Question
The Obscure Question

Reputation: 1174

The logic in your list comprehension is fine. You can verify this by changing

print {x:y for x,z in scrabble_scores for y in z}

to

print [(x,y) for x,z in scrabble_scores for y in z]

which prints out

[(1, 'E'), (1, 'A'), (1, 'O'), (1, 'I'), (1, 'N'), (1, 'R'), (1, 'T'), (1, 'L'), (1, 'S'), (1, 'U'), (2, 'D'), (2, 'G'), (3, 'B'), (3, 'C'), (3, 'M'), (3, 'P'), (4, 'F'), (4, 'H'), (4, 'V'), (4, 'W'), (4, 'Y'), (5, 'K'), (8, 'J'), (8, 'X'), (10, 'Q'), (10, 'Z')]

The reason why your implementation doesn't work is because each key of the dictionary must be unique. Therefore, when you're setting 1:A, the previous key:value pair of 1:E is overwritten.

Maybe you're looking for the letter to be the key? If so, then just swap x and y:

print {y:x for x,z in scrabble_scores for y in z}

Upvotes: 0

Related Questions