Kyle C
Kyle C

Reputation: 121

Return values from a lambda expression

I am importing values from a SQLite database and wanting to run a lambda expression over one of the columns to create a list.

cur.execute('SELECT p, T FROM W')
data = cur.fetchall()

lst = list()
for row in data:
    p = float(row[0])
    T = float(row[1])
    lst.append(lambda T: p if T < 1 else 0)

When I run this the output is a list of the following:

< function <lambda> at 0x00000255E52AA8C8> . 

I am wanting to append the list with the value of p when T < 1 and 0 if T > 1.

Upvotes: 0

Views: 520

Answers (4)

tkiral
tkiral

Reputation: 49

You don't need the lambda expression.

You can think of it like this: currently, you're telling the computer to append the function itself to the list; you're not telling the computer to append the evaluation of that value. If you get rid of the lambda T: bit, you're basically doing an inline if-statement that DOES evaluate the value. Lambda functions are used to define single-line functions to be used later.

Upvotes: 0

DeepSpace
DeepSpace

Reputation: 81594

You already got 2 great answers so I'm going to suggest another approach. This can be solved on the query level, assuming you are actually only selecting these 2 columns with the logic you showed us.

This has the potential for better performance if there are a lot of rows in the table:

cur.execute('SELECT CASE WHEN T < 1 THEN p WHEN T > 1 THEN 0 END FROM W')
data = cur.fetchall()

Then you do not need the loop as data already contains what you need. Just keep in mind this query will return None for rows in which T == 1, but that can be easily handled with another WHEN.

Upvotes: 1

user2390182
user2390182

Reputation: 73460

No lambda needed at all:

lst.append(p if T < 1 else 0)

The ternary expression itself will do. In order to get the return value of the lambda function, it would have to be called, something along these lines:

lst.append((lambda: p if T < 1 else 0)())

This, of course, is rather pointless. A lambda function can only contain a single expression. Instantly calling it makes the function obsolete, as you are back to the bare expression. That is why such functions often take arguments that are dynamically filled by the context into which the function is passed. This lambda wouldn't even need arguments as all needed parts are there, ready to be used.

Upvotes: 5

Sheldore
Sheldore

Reputation: 39052

An alternative solution would be to consider list comprehension to create you final list lst. This way you can also avoid the use of intermediate variables. Of course this is just a one liner to solve your problem.

lst = [float(row[0]) if float(row[1]) < 1 else 0 for row in data]

Upvotes: 2

Related Questions