Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - Use a print/debug statement within a Lambda

I have a filter in Python3 that I am applying with a lambda function. Here is my function:

affy_reader = csv.DictReader(filter(lambda row:
                                    not row[0].startswith('#') and
                                    str(row[0]).isdigit(),
                                    file_pointer), 
                             delimiter='\t',
                             fieldnames=affy_column_headers)

Is there a way that I can print the value of row from within this lambda function? I think I need to do it like this because row is only scoped within the lambda. For example, were this a LISP Lambda procedure, I believe I could do something like this:

affy_reader = csv.DictReader(filter(lambda row: print(row) 
                                    not row[0].startswith('#') and
                                    str(row[0]).isdigit(),
                                    file_pointer), 
                             delimiter='\t',
                             fieldnames=affy_column_headers)

Because the print() is read and executed in-line. Is there some way in Python to do this? Or if not, what is a good way for me to see this value? Thanks!

*I realize my "LISP" example is Python not LISP. I was just trying to illustrate further what it is I am trying to do.

like image 234
Houdini Avatar asked Jun 06 '13 17:06

Houdini


2 Answers

I don't think you can do it with a lambda. Just define a helper function. That way you can also display whether a certain row is or isn't going to be filtered:

def filter_plus_print(row):
    result = not row[0].startswith('#') and str(row[0]).isdigit()
    print("Keeping:" if result else "Removing:", row)
    return result

and then do

affy_reader = csv.DictReader(filter(filter_plus_print, file_pointer), 
                             delimiter='\t',
                             fieldnames=affy_column_headers)
like image 196
Tim Pietzcker Avatar answered Sep 28 '22 10:09

Tim Pietzcker


General Python 3.x trick to print debug info in a lambda without changing its semantics:

Original:

lambda: 4

Instrumented:

lambda: (print (3), 4) [1]

Explanation:

Both arguments of the tuple will be evaluated.

The left one, print (3) in the example, is relying purely on a sideeffect, i.e. in this case it will print something. You can call any function here, since any Python function will return a value. This value will be the Python predefined value None if a return statement is missing. This doesn't matter since the return value isn't used anywhere.

The second argument, 4 in the example, can be any expression including a function call or a call to a functor (object with overloaded round brackets). This argument is returned by the lambda function by selecting [1], i.e. the second element of the tuple (indexing in Python starts at 0].

The reason why this works specifically in Python 3.x is that print is a "perfectly ordinary" function there, whereas in Python 2.x it was a statement.

like image 27
Jacques de Hooge Avatar answered Sep 28 '22 08:09

Jacques de Hooge