Hey folks.So my code looks like this :

> score = {"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}
> def scrabble_score(word):
>   return sum(score[item] for item.lower() in list(word)

And it throws me an error:
“Did you create a function called scrabble_score? Your code threw a “global name ‘item’ is not defined” error.”

Tried also “x.lower”, and some variations like str(x.lower) or str(x).lower and also doesnt seem to work. Can anybody point me in good direction? Cheers.`


Your error message mentions a name which you use in two places. That gives you opportunity to try changing one at a time and see if it resolves it and when you’ve figured out which, reconsider what can be done there.

Googling examples of list comprehensions also gives you something to compare to. (strictly speaking that’s a generator expression, not a list comprehension, but aside from the outermost brackets they’re written the same way)


Hm.I’ve been looking for some time for a list or generator comprehension example with an operation on one of the parameter like “lower()” and I couldnt find anything.All I need to know is how should I use the lower() on my “item”, sounds easy but I think I exhausted all the options based on my little programming knowledge with no result and im stuck.


A list comprehension has multiple parts in it, one for describing the result, one for specifying an iterable, one for specifying variables for the iteration, and one for conditionally including that iteration in the result.

What does str.lower do and in which part(s) does it therefore at all make sense to use it in? Worst case you can try everything, but there’s something to be said for describing what you mean instead of describing all possibilities and picking the one that matches.

What if you rewrote it as a regular loop just for the sake of observing where you put it? It’s not all that different, they both have parts specifying what to do what to iterate through, where to put values from the iterable

Also, there’s nothing special about str.lower in a list comprehension, so an example wouldn’t have to include specifically that

Should also point out that strings are iterable. That’s why it’s possible to convert them to list (which you do, but probably to make it iterable, which it already is)


Thanks for replying once again.
What do you mean by “as a regular loop”? Wouldnt be it slower?

str.lower is meant to be for the capital letters which are given in “text” variable but not in the “score” dict, and this task is to sum values for keys in “text” based on their score.values.

I guess I can add a line or two to make it work in some way around it, but is it the best way to do it? I dont want to learn a bad habit if there is any shorter way for it.


Slower? Maybe. In a way that matters? Not in the slightest, it’s still a constant amount of time spent on each character.

For example if you have a phone book and want to count how many times “John” is in it, it would be fast to read through the phone book once and add 1 to some variable each time “John” is encountered, but it would be slow to start over each time a new “John” is encountered. Whether the last name is checked as well is insignificant, it’s not worth considering.

My guess would actually be that it’s faster because generators come with some overhead. List comprehension might be faster. But that’s guessing, and either way it’s insignificant so I won’t bother figuring out which is the case.

In any case, the reason for writing a regular loop is only for figuring out what goes where. They have the same parts - a place where something’s done, a place to specify an iterable, a place for creating variables.

If I wanted to add 3 to each number in some list, I would do that in the body of the for-loop, wouldn’t I? Converting to lowercase is a similar action, it would go in the same place.

What if you tried to write a function like this?:

def add(c = a + b):
    return c

Is that valid python? For all you know this might be some fancy feature, it might be valid. But you’d probably think that it should look like this instead:

def add(a, b):
    return a + b

Because the function body is where actions are meant to be carried out, not in the argument list.

(and it is valid, but does something else because the different parts in the function statement are treated differently or otherwise there may as well only be one part to it)

A for-loop?

results = []
for c = a + b in numbers:

Not quite huh.

Same thing with list comprehension. Look at what the different parts do and put code where you need it to be. Lots of examples to be found by searching, and you can modify those examples to see how they affect the outcome.