8

I wanted to use lambdas inside for loops to return if certain elements are non-numerical:

strs = ['1234', 'hello', '6787']

I can use a for loop and iterate through each element:

for elem in strs:

and check elem.islpha().

However, is there a way to use lambdas coupled with a for loop to return the word "hello"?

2
  • So it sounds like you have a working solution. Why do you want to use lambda expressions? It isn't needed and won't provide anything over a list comprehension, normal for loop, etc. Commented Jun 14, 2013 at 2:13
  • Just for interest, I wanted to understand Commented Jun 14, 2013 at 2:22

5 Answers 5

17

Try this, it's easy using a list comprehension:

lst =  ['1234', 'hello', '6787']
[x for x in lst if x.isalpha()]
=>  ['hello']

Or if you definitely want to use a lambda:

filter(lambda x: x.isalpha(), lst)
=>  ['hello']

Notice that you'll rarely use lambdas for filtering inside a for loop, it's not idiomatic. The way to go for filtering elements out of a list is using list comprehensions, generator expressions or (less recommended) the filter() built-in function.

Sign up to request clarification or add additional context in comments.

6 Comments

Suppose, my list was list = [u'\n', u'test', u'\t'] would I need to convert the list entries to strings and then check .isalpha()?
I think if there is space in test to test and some stuff .isalpha() breaks down
@MaxKim then you should check if not x.is_number(), use the function defined in this question
Or, could I do x.strip().isalpha()?
@MaxKim or even better, make sure that your list doesn't contain spaces in the first place. Use split() in the input string
|
4

Firstly, become accustomed to list comprehensions:

>>> strs = ['1234', 'hello', '6787']
>>> [s for s in strs if s.isalpha()]
['hello']

They are the most adaptable and in most cases, the most readable way of doing this. Then why would you use map? map is fast and good looking for simple cases:

>>> map(str.upper, strs)
['1234', 'HELLO', '6787']

But the instance you have to use lambda, map becomes ugly and slow. This rule also applies for filter.

In [1]: strs = ['1234', 'hello', '6787']

In [2]: %timeit map(lambda s: s[0] if s.isalpha() else s, strs)
1000000 loops, best of 3: 1.48 us per loop

In [3]: %timeit [s[0] if s.isalpha() else s for s in strs]
1000000 loops, best of 3: 799 ns per loop

Many people have suggested

>>> filter(lambda s: s.isalpha(), strs)
['hello']

But remember lambda s: s.isalpha() is just fluff for str.isalpha, the method of the string class.

>>> filter(str.isalpha, strs)
['hello']

This makes it clean and fast to use filter here, but remember the consequences once you involve lambdas.

Implementation detail of Python 2.x

Unfortunately python 2.x has two different string types (In python 3 there is only str which is unicode) str and unicode. Therefore the clean solution using str.isalpha won't work. You could simply change this to unicode.isalpha but if you are mixing unicode and str you need something cross compatible.

One alternative is to use methodcaller

>>> strs = [u'\n', u'test', u'\t']
>>> from operator import methodcaller
>>> filter(methodcaller('isalpha'), strs)
[u'test']

But this isn't very straightforward, that's why it's nice to just use list comprehensions to avoid this trouble.

>>> [s for s in strs if s.isalpha()]
[u'test']

2 Comments

(1) str.isalpha doesn't return an uppercase copy, that's str.upper. :^) (2) str.isalpha won't work if the OP has Python 2 unicode strings as suggested in his comment ([u'\n', u'test', u'\t']).
@DSM I fixed (1), didn't see 2, I will add that to my answer
2

If you really need to use lambda, or you are learning functional programming, you can use filter:

>>> filter(lambda x:x.isalpha(), ['123','hello','456'])
['hello']

Using lambda inside a loop makes no sense in your context, since you can call x.isalpha() directly

Comments

0

If what you want is to pull non-numerical items from a list, I don't see the need to use a lambda.

alphas = [item for item in strs if item.isalpha()]

Comments

0

This is probably what you're looking for. You can't use a for loop explicitly, but you can use a generator expression:

check_isalpha = lambda lst: (elem for elem in lst if elem.isalpha())[0]

2 Comments

That's a list comprehension, not a generator expression.
@Anorov I had it as a generator originally :P I'll change it back, though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.