2

Can somebody explain to me why the following code produces an error:

fruit_lst = ["Apple", "Banana", "Pear", "Apricot", "Orange"]
filtered_lst = filter(lambda x: x if x[0]=="A", fruit_lst)

I'm trying to print out the values which start with the letter A.

3
  • 1
    Because x if x[0]=="A" isn't a valid expression. What's the value if it's not equal to A? Probably you just wanted to return the condition itself to be used to filter the list. Commented Sep 13, 2021 at 19:53
  • 3
    A ternary expression requires an else clause. Commented Sep 13, 2021 at 19:53
  • 2
    "an error" - please be specific. The traceback message would help. Commented Sep 13, 2021 at 20:01

7 Answers 7

3

You're getting a syntax error because an if expression has to include else, there's no default value.

But you don't need if here. The callback function of filter() just needs to return a boolean, so just use the comparison.

filtered_lst = filter(lambda x: x.startswith('A'), fruit_lst)

Note that filter() is generally not considered pythonic, conditional list comprehensions are usually preferred.

filtered_lst = [x for x in fruit_lst if x.startswith('A')]
Sign up to request clarification or add additional context in comments.

Comments

2

filter works by expecting True or False in order to keep the values in the list, so your way can be fixed to

filtered_lst = list(filter(lambda x: True if x[0]=="A" else False, fruit_lst))

However, its more correct to do it like this:

filtered_lst = list(filter(lambda x: x[0]=="A", fruit_lst))

Or

filtered_lst = [x for x in fruit_lst if x[0]=="A"]

1 Comment

I would argue that it is not "more correct" to do it like that, just a bit shorter and more elegant :)
0

You Have to add else in inline if statement

for example:

fruit_lst = ["Apple", "Banana", "Pear", "Apricot", "Orange"]
filtered_lst = filter(lambda x: x if x[0]=="A" else 0, fruit_lst)

Comments

0

Your condition is incomplete. It can be corrected like this.

fruit_lst = ["Apple", "Banana", "Pear", "Apricot", "Orange"]
filtered_lst = filter(lambda x: True if x[0]=="A" else False , fruit_lst)
for s in filtered_lst:
    print(s)

Output

Apple
Apricot

Comments

0

The construct if x[0]=="A" is not valid syntax. That's what the error tries to tell you.

The reason it is not valid is that you can not just return only sometimes from the lambda function. You'll have to define what it should return.

Having a look at the filter documentation we can see

filter(function, iterable)
Construct an iterator from those elements of iterable for which function returns true.

So what you want is to have a lambda function that returns either True or False, depending on whether the item should be kept.

 filter(lambda x: x[0]=="A", fruit_lst)

This does the trick. Note that it returns not a list, but a "filter object". If you want to have a list instead of an iterable (e.g. for debug printing), you will have to use list() on this.


By the way (just as a fun fact), if you wanted to use if somewhere in your code, you could also do this:

filtered_lst = [x for x in fruit_lst if x[0]=="A"]

Here, the if without else is allowed because it's a different syntactic construct. It says "take x if it fulfills this, and do not take it otherwise"

Comments

0

The error you get is SyntaxError: invalid syntax. The reason is that you need to provide the else statement in the if ... else structure. A solution would be to supply the else statement shown in the code snippet below:

fruit_lst = ["Apple", "Banana", "Pear", "Apricot", "Orange"]
filtered_lst = filter(lambda x: x if x[0]=="A" else None, fruit_lst)

Also, if you would like to view the filtered_lst as a Python list, make sure to convert the filter object resulting from the filter operation to a list as follows:

filtered_lst = list(filter(lambda x: x if x[0]=="A" else None, fruit_lst))

If you were then to print out the list called filtered_lst, you'd get the desired result as follows:

['Apple', 'Apricot']

EDIT: Having read the previous answers, this one seems the most elegant one.

Comments

0

Use list comprehension with re.findall, to find the elements in your list that start with "A":

import re
fruit_lst = ["Apple", "Banana", "Pear", "Apricot", "Orange"]
filtered_lst = [s for s in fruit_lst if re.findall(r'^A', s)]
print(filtered_lst)
# ['Apple', 'Apricot']

Note that this method allows you to easily extend the code to other related functionalities, such as to find elements that start with "a" in case-insensitive way:

fruit_lst = ["Apple", "Banana", "Pear", "Apricot", "Orange", "apple"]
filtered_lst = [s for s in fruit_lst if re.findall(r'^a', s, re.IGNORECASE)]
print(filtered_lst)
# ['Apple', 'Apricot', 'apple']

Or those that have "p" anywhere, case-insensitive:

fruit_lst = ["Apple", "Banana", "Pear", "Apricot", "Orange", "apple"]
filtered_lst = [s for s in fruit_lst if re.findall(r'p', s, re.IGNORECASE)]
print(filtered_lst)
# ['Apple', 'Pear', 'Apricot', 'apple']

Comments

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.