It is strange how much beauty varies for different people. I find the list comprehension much clearer than filter+lambda, but use whichever you find easier.
There are two things that may slow down your use of filter.
The first is the function call overhead: as soon as you use a Python function (whether created by def or lambda) it is likely that filter will be slower than the list comprehension. It almost certainly is not enough to matter, and you shouldn't think much about performance until you've timed your code and found it to be a bottleneck, but the difference will be there.
The other overhead that might apply is that the lambda is being forced to access a scoped variable (value). That is slower than accessing a local variable and in Python 2.x the list comprehension only accesses local variables. If you are using Python 3.x the list comprehension runs in a separate function so it will also be accessing value through a closure and this difference won't apply.
The other option to consider is to use a generator instead of a list comprehension:
def filterbyvalue(seq, value):
for el in seq:
if el.attribute==value: yield el
Then in your main code (which is where readability really matters) you've replaced both list comprehension and filter with a hopefully meaningful function name.
Answer from Duncan on Stack OverflowIt is strange how much beauty varies for different people. I find the list comprehension much clearer than filter+lambda, but use whichever you find easier.
There are two things that may slow down your use of filter.
The first is the function call overhead: as soon as you use a Python function (whether created by def or lambda) it is likely that filter will be slower than the list comprehension. It almost certainly is not enough to matter, and you shouldn't think much about performance until you've timed your code and found it to be a bottleneck, but the difference will be there.
The other overhead that might apply is that the lambda is being forced to access a scoped variable (value). That is slower than accessing a local variable and in Python 2.x the list comprehension only accesses local variables. If you are using Python 3.x the list comprehension runs in a separate function so it will also be accessing value through a closure and this difference won't apply.
The other option to consider is to use a generator instead of a list comprehension:
def filterbyvalue(seq, value):
for el in seq:
if el.attribute==value: yield el
Then in your main code (which is where readability really matters) you've replaced both list comprehension and filter with a hopefully meaningful function name.
This is a somewhat religious issue in Python. Even though Guido considered removing map, filter and reduce from Python 3, there was enough of a backlash that in the end only reduce was moved from built-ins to functools.reduce.
Personally I find list comprehensions easier to read. It is more explicit what is happening from the expression [i for i in list if i.attribute == value] as all the behaviour is on the surface not inside the filter function.
I would not worry too much about the performance difference between the two approaches as it is marginal. I would really only optimise this if it proved to be the bottleneck in your application which is unlikely.
Also since the BDFL wanted filter gone from the language then surely that automatically makes list comprehensions more Pythonic ;-)
The use of filter, according to me requires a function and a sequence object. Filter then creates a filter object that will eventually be run to filter out those elements which the function returns true on each object in the sequence.
But, I have a lambda that takes two parameters, how do I run filter on lambda and that sequence?
My exact problem is:
The lambda function is:
f = lambda div, keyword : div.attrs.get('class') and keyword in div.attrs.get('class')[0]
Where div would be a beautifulsoup element object and keyword would be a string. And the function f checks if the keyword is there in the class attribute of div or not.
And I have a collection of divs which I want to filter out with f.
Usually I'd write a for loop like this:
filtered_divs = list()
for div in divs:
if f(div, keyword):
filtered_divs.append(div)
Is it worth it to even use lambda and filter in this case? I'm very new to these functions in python and don't know when they should be used instead of a for loop. Thanks
Hello Pythonistas!
I've been on a Python journey recently, and I've found myself fascinated by the power and flexibility of Lambda functions. These anonymous functions have not only made my code more efficient and concise, but they've also opened up a new way of thinking about data manipulation when used with Python's built-in functions like Map, Filter, and Reduce.
Lambda functions are incredibly versatile. They can take any number of arguments, but can only have one expression. This makes them perfect for small, one-time-use functions that you don't want to give a name.
Here's a simple example of a Lambda function that squares a number:
square = lambda x: x ** 2
print(square(5)) # Output: 25
But the real power of Lambda functions comes when you use them with functions like Map, Filter, and Reduce. For instance, you can use a Lambda function with `map()` to square all numbers in a list:
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, numbers))
print(squared) # Output: [1, 4, 9, 16, 25]
You can also use a Lambda function with `filter()` to get all the even numbers from a list:
numbers = [1, 2, 3, 4, 5]
even = list(filter(lambda x: x % 2 == 0, numbers))
print(even) # Output: [2, 4]
And finally, you can use a Lambda function with `reduce()` to get the product of all numbers in a list:
from functools import reduce
numbers = [1, 2, 3, 4, 5]
product = reduce(lambda x, y: x * y, numbers)
print(product) # Output: 120
Understanding and using Lambda functions, especially in conjunction with Map, Filter, and Reduce, has significantly improved my data manipulation skills in Python. If you haven't explored Lambda functions yet, I highly recommend giving them a try!
Happy coding!