-1
def presses(phrase):
    i = 0
    for char in phrase.upper():
        if char in '1ADGJMPTW*#':
            i += 1
        if char.isspace() == True:
            i += 1
        if char in 'BEHKNQUX0':
            i += 2
        if char in 'CFILORVY':
            i += 3
        if char in '23456S8Z':
            i += 4
        if char in '79':
            i += 5
    return i    

I've recently completed a python puzzle in an attempt to better my scripting ;however, I've tried turning my loop into a comprehension, but I'm having trouble doing this because of all the conditionals. Can anyone help me try and turn this loop into a comprehension?

juanpa.arrivillaga
  • 88,713
  • 10
  • 131
  • 172
  • I think [this question](https://stackoverflow.com/questions/10272898/multiple-if-conditions-in-a-python-list-comprehension/10272927) has a few useful answers and some helpful discussion to dissect the answers. – gallen Jun 29 '20 at 22:22
  • Why do you want to turn this into a comprehension construct? Those produce various containers or generators, you are simply counting things and returning an `int`... Given the structure of what you are doing, it's going to be much cleaner as a regular for-loop. – juanpa.arrivillaga Jun 29 '20 at 22:23
  • Does this answer your question? [Multiple IF conditions in a python list comprehension](https://stackoverflow.com/questions/10272898/multiple-if-conditions-in-a-python-list-comprehension) – adamgy Jun 29 '20 at 22:24
  • 2
    A list comprehensions is for creating a list. A dict comprehensions is for creating a dict. You're calculating an int. There's no such thing as an int comprehension. – khelwood Jun 29 '20 at 22:24
  • @adamgy not really comparable, conditional expressions arequire an `if-else`, not various `if`s, at least, it won't be semantically equivalent. – juanpa.arrivillaga Jun 29 '20 at 22:24
  • The canoncal is https://stackoverflow.com/questions/4260280, but it really isn't appropriate to try to chain all the `if`s together in a single comprehension like this. Instead, use a function to encapsulate the logic for a single element, then write a list comprehension to use that. – Karl Knechtel Jan 30 '23 at 05:51
  • @khelwood clearly, the intent is to use a list comprehension to determine the values to add up, and then add them with `sum` etc. – Karl Knechtel Jan 30 '23 at 05:51
  • @KarlKnechtel I can see that is a possible interpretation; or they could be using the word "comprehension" mistakenly when what they actually need is a generator. – khelwood Jan 30 '23 at 09:31

3 Answers3

1

If your increment rules are based on simple strings, then I would create a lookup table and iterate over your input string:

lookup = {
    '1': 1,
    'A': 1,
    ...
    '7': 5,
    '9': 5,
}

output = sum(lookup[char] for char in phrase)
trianta2
  • 3,952
  • 5
  • 36
  • 52
1

To add to @trianta2, if you don't want a lookup dictionary (for some reason), you can do this:

def presses_v2(phrase):
    return sum(1 if c in '1ADGJMPTW*# \t' else 2 if c in 'BEHKNQUX0' else 3 if c in 'CFILORVY' else 4 if c in '23456S8Z' else 5 if c in '79' else 0 for c in phrase.upper())

Note that your 2nd if-statement can be included in the first:

if char in '1ADGJMPTW*# \t':
    i += 1

I also changed char to c, to make the line shorter.

ori6151
  • 592
  • 5
  • 11
0

I don't get why would you want a list comprehension of this, since your code is easier to understand as you have it now, but.... I would try this way, it's messy but it works.

i = [z for x, z in [('1ADGJMPTW*#', 1), (" ", 1), ('BEHKNQUX0', 2), ('CFILORVY', 3), ('23456S8Z', 4), ('79', 5)] for char in phrase.upper() if char in x]

It's based on the logic that every IF that you have can be divided into 2 parts of a tuple, the condition and the result, knowing that you just have to build a list of tuples and iteract it. It gives you a list of the value of each character.

If you want the total, just sum it:

i = sum([z for x, z in [('1ADGJMPTW*#', 1), (" ", 1), ('BEHKNQUX0', 2), ('CFILORVY', 3), ('23456S8Z', 4), ('79', 5)] for char in phrase.upper() if char in x])  
Saelyth
  • 1,694
  • 2
  • 25
  • 42