2

I am trying to convert this function:

templist = []
for each in characters:
    if each in vowels:
        templist.append('v')
    elif (each in alphabet) & (each not in vowels):
        templist.append('c')
    else:
        templist.append('?')
characters = templist
print(characters)

into list comprehension

modified_list = ['v' for each in characters for item in vowels 
                     if item in vowels 
                 else 'c' if (item in alphabet) & (item not in vowels)
                 else '?']`

Kinda stuck here! Can't figure out what I am doing wrong.

Prune
  • 76,765
  • 14
  • 60
  • 81
  • 1
    Why are you using `&` instead of `and`? – juanpa.arrivillaga Nov 16 '17 at 00:02
  • 1
    Also, why do you want to cram everything into a list comprehension? The original code format is much more readable. – roganjosh Nov 16 '17 at 00:05
  • 1
    Yes, and note, if you ever *do* read your elif, the `not in vowels` will *always be `True`, since you already first check `if each in vowels` – juanpa.arrivillaga Nov 16 '17 at 00:06
  • @roganjosh you want to use list comprehensions where you can as list comprehensions gain performance boosts in python. In this case, a list comprehension is the best structure to use to iterate *and* return a list. If they were just iterating a loop and not expecting an array out of it, a normal for loop would be most performant. – adambullmer Nov 16 '17 at 00:13
  • @adambullmer I'm actually not sure that your solution is any faster than the OP's original code (though I'm not saying it's not an elegant approach). You now have a function call overhead for every item in the list (which may or may not balance against `append` cost). You'd have to use `timeit` to see. – roganjosh Nov 16 '17 at 00:15
  • Its class assignment. @roganjosh – user3035168 Nov 16 '17 at 00:42
  • 1
    @adambullmer I *highly highly* disagree. You should use a list-comprehension where it is *readable*, doesn't use side-effects, and you want a `list` as an end-result. The performance gains from list-comprehensions are marginal. – juanpa.arrivillaga Nov 16 '17 at 00:54

3 Answers3

3

Sometimes it's best to make a function to be called in your list comprehension. Still gives you the speed improvements of a list comprehension while cleaning up the insides a bit.

def char_code(character):
  if character in vowels:
    return 'v'
  elif character in alphabet:
    return 'c'
  else:
    return '?'

print([char_code(c) for c in characters])
adambullmer
  • 952
  • 9
  • 29
3

You had several errors in your comprehension syntax. Most of all, you inserted your for clause into the middle of your conditional expression; it has to go at the end of the expression.

modified_list = ['v' if each in vowels else
                ('c' if each in alphabet else '?')
                     for each in characters]

I also removed the useless for clauses, and the redundant test for a consonant: when you're in the else clause of your expression, you already know it's not a vowel -- no need to re-test.

FULL TEST

vowels = "aeiou" alphabet = "qwertyuiopasdfghjklzxcvbnm" characters = "Now is the time"

templist = []
for each in characters:
    if each in vowels:
        templist.append('v')
    elif (each in alphabet) & (each not in vowels):
        templist.append('c')
    else:
        templist.append('?')

print("     original", ''.join(templist))

modified_list = ['v' if each in vowels else \
                ('c' if (each in alphabet) else '?') \
                     for each in characters]

print("comprehension", ''.join(modified_list))

Output:

     original ?vc?vc?ccv?cvcv
comprehension ?vc?vc?ccv?cvcv
Prune
  • 76,765
  • 14
  • 60
  • 81
1

just a line breaking style mention: Is it possible to break a long line to multiple lines in Python shows some options

the list comp brackets in this case make \ unnecessary

sometimes I play with leading space inside the line continuation to indicate logical hiearchy - the leading space is syntactically ignored inside a code line continuation

['v' if each in vowels
     else ('c' if each in alphabet
               else '?')
 for each in characters]
f5r5e5d
  • 3,656
  • 3
  • 14
  • 18