Trebond
Trebond

Reputation: 57

Lambda Expressions and Strings

I am just learning about lambda expressions, and I am wondering how I could use it to count the number of vowels in a string. For example, I am using the following:

result = lambda i, y: i + 1 for x in y if x in "aeoiuAEIOU"
print(result(0,s)

However, I recieve a syntax error. Also, just to clarify my understanding, a lambda expression returns the expression following the colon. Could someone please point me in the right direction?

Upvotes: 0

Views: 1513

Answers (4)

LiuXiMin
LiuXiMin

Reputation: 1265

You can also just use one parameter in lambda:

result = lambda y: sum(x in "aeoiuAEIOU" for x in y)

and the syntax error is not special with lambda:

In [10]: def bar(i, y):
    ...:     return i + 1 for x in y if x in "aeoiuAEIOU"
  File "<ipython-input-10-96fcd0959145>", line 2
    return i + 1 for x in y if x in "aeoiuAEIOU"
                   ^
SyntaxError: invalid syntax

the real issue is that i + 1 for x in y if x in "aeoiuAEIOU" is an invalid expression in Python.

Upvotes: 1

Jab
Jab

Reputation: 27515

To me this is an improper use of lambda to begin with, as lambda's are supposed to be function definitions with no name or more or less a throw away function. Also the reason you got a Syntax Error is your generator expression is incorrect, use sum for something like this.

result = lambda y: sum(1 for x in y if x in "aeoiuAEIOU")

You can even use map for this:

result = lambda y: sum(map(y.count, "aeoiuAEIOU"))

But this could be done more legibly and imo more correctly with an actual function definition and you can include more statements

#more appropriately named count_vowels vs result and s vs y
def count_vowels(s):
    _s = s.lower()
    return sum(map(_s.count, 'aeiou')

You can also use re (regex) for this too:

import re

def count_vowels(s): return len(re.findall("[aeiou]", s, re.I))

The re.I ignores case so no need to worry about capsvs uncaps

Upvotes: 1

Trebond
Trebond

Reputation: 57

Thank you Silvio for your help! Populating a list like you suggested gave me an answer that wasn't quite as clear as I wanted as it returned

[1, 1, 1, 1, 1]

While a generator returned

<generator object <lambda>.<locals>.<genexpr> at 0x0000028884166C00>

In the end, I used sum on the generator to get

result = lambda i, y: sum(i + 1 for x in y if x in "aeoiuAEIOU")
print(result(0, s))

Which gave me the answer of 5.

Upvotes: 1

Silvio Mayolo
Silvio Mayolo

Reputation: 70297

It's just the parse that's ambiguous. Consider

result = lambda i, y: (i + 1 for x in y if x in "aeoiuAEIOU")

Of course, now it will return a generator object, which won't print as nicely. If you want a list, you might try

result = lambda i, y: [i + 1 for x in y if x in "aeoiuAEIOU"]

Upvotes: 2

Related Questions