Altering the definition of a function without an assignment - python

I was given this task:
Write a one-line expression that transforms an f(x) function into f(x)
+1. Hint: think about how a local frame binding for saved value of f, can be created without an assignment.
Example:
>>> f = lambda x: x*x
>>> f(5) 25
>>> ---your one line expression---
>>> f(5) 26
>>> f, g = None, f
>>> g(5) 26
I tried to do this:
k,f=f, lambda x: k(x)+1
And it works but it uses the assignment f=f. How could I do this without an assignment?
My teacher told me that there is a function in Python similar to the let function in Scheme, but I'm not sure what this function is that she wants us to use because she did not provide the name of the function.

This is not something that should be used in general, but I suppose you could do this:
def f(x, f=f): return f(x) + 1
And there's "no (explicit) assignments" since we're just defining a new function name which happens to be the same as the original.

This will work, but it may be cheating:
>>> f = lambda x: x*x
>>> f(5)
25
>>> globals().update({'f': (lambda g: lambda x: g(x)+1)(f)})
>>> f(5)
26
>>> f, g = None, f
>>> g(5)
26

Related

What is the Python equivalent of LINQ OfType<T>() (in .NET)

I am trying to get a single Handler of a specific custom type MemoryListHandler in the logger.handlers collection.
With .NET I would simply use the following LINQ extension, which filters element and returns only those of type MemoryListHandler:
logger.handlers.OfType<MemoryListHandler>().SingleOrDefault()
What would be the most elegant equivalent in Python?
My current (not very neat) attempt is:
next((handler for handler in logger.handlers if handler is MemoryListHandler), None)
You might try the index method.
try:
lh = logger.handlers
x = lh[lh.index(MemoryListHandler)]
except ValueError:
x = some_default_value
Python is dynamically typed, therefore you might not need to convert anything.
However, in some cases you still might need to convert, say, int to string :
map(lambda x: str(x), [1, 2, 3])
Or, given your function accepts only one argument, just pass the function alone :
map(str, [1, 2, 3])
Update
filter(lambda x: type(x) == YourClass, [your_array])
For Python the is operator tests identity NOT type like it does in c#. You want isinstance for your test -- which will also work with subtypes of the target_type you're looking for.
Using the Python REPL to illustrate the difference between is and isinstance:
>>> s = ""
>>> s is str
False
>>> isinstance(s, str)
True
>>> class Foo:
... def __init__(self):
... pass
...
>>> f = Foo()
>>> g = Foo()
>>> f is g
False
>>> f is Foo
False
>>> g is Foo
False
>>> x = f
>>> f is x
True
>>> g is x
False
Your own expression is pretty close to what you want. You can hide it behind a method:
def first_of_type(xs, target_type):
return next((x for x in xs if isinstance(x, target_type)), None)
Usage becomes short and sweet:
first_of_type(logger.handlers, MemoryListHandler)
Note: addition of type hints and doc comments would help usability.

loop for inside lambda

I need to simplify my code as much as possible: it needs to be one line of code.
I need to put a for loop inside a lambda expression, something like that:
x = lambda x: (for i in x : print i)
Just in case, if someone is looking for a similar problem...
Most solutions given here are one line and are quite readable and simple. Just wanted to add one more that does not need the use of lambda(I am assuming that you are trying to use lambda just for the sake of making it a one line code).
Instead, you can use a simple list comprehension.
[print(i) for i in x]
BTW, the return values will be a list on None s.
Since a for loop is a statement (as is print, in Python 2.x), you cannot include it in a lambda expression. Instead, you need to use the write method on sys.stdout along with the join method.
x = lambda x: sys.stdout.write("\n".join(x) + "\n")
To add on to chepner's answer for Python 3.0 you can alternatively do:
x = lambda x: list(map(print, x))
Of course this is only if you have the means of using Python > 3 in the future... Looks a bit cleaner in my opinion, but it also has a weird return value, but you're probably discarding it anyway.
I'll just leave this here for reference.
anon and chepner's answers are on the right track. Python 3.x has a print function and this is what you will need if you want to embed print within a function (and, a fortiori, lambdas).
However, you can get the print function very easily in python 2.x by importing from the standard library's future module. Check it out:
>>>from __future__ import print_function
>>>
>>>iterable = ["a","b","c"]
>>>map(print, iterable)
a
b
c
[None, None, None]
>>>
I guess that looks kind of weird, so feel free to assign the return to _ if you would like to suppress [None, None, None]'s output (you are interested in the side-effects only, I assume):
>>>_ = map(print, iterable)
a
b
c
>>>
If you are like me just want to print a sequence within a lambda, without get the return value (list of None).
x = range(3)
from __future__ import print_function # if not python 3
pra = lambda seq=x: map(print,seq) and None # pra for 'print all'
pra()
pra('abc')
lambda is nothing but an anonymous function means no need to define a function like def name():
lambda <inputs>: <expression>
[print(x) for x in a] -- This is the for loop in one line
a = [1,2,3,4]
l = lambda : [print(x) for x in a]
l()
output
1
2
3
4
We can use lambda functions in for loop
Follow below code
list1 = [1,2,3,4,5]
list2 = []
for i in list1:
f = lambda i: i /2
list2.append(f(i))
print(list2)
First of all, it is the worst practice to write a lambda function like x = some_lambda_function. Lambda functions are fundamentally meant to be executed inline. They are not meant to be stored. Thus when you write x = some_lambda_function is equivalent to
def some_lambda_funcion():
pass
Moving to the actual answer. You can map the lambda function to an iterable so something like the following snippet will serve the purpose.
a = map(lambda x : print(x),[1,2,3,4])
list(a)
If you want to use the print function for the debugging purpose inside the reduce cycle, then logical or operator will help to escape the None return value in the accumulator variable.
def test_lam():
'''printing in lambda within reduce'''
from functools import reduce
lam = lambda x, y: print(x,y) or x + y
print(reduce(lam,[1,2,3]))
if __name__ =='__main__':
test_lam()
Will print out the following:
1 2
3 3
6
You can make it one-liner.
Sample
myList = [1, 2, 3]
print_list = lambda list: [print(f'Item {x}') for x in list]
print_list(myList)
otherList = [11, 12, 13]
print_list(otherList)
Output
Item 1
Item 2
Item 3
Item 11
Item 12
Item 13

Determining the method called within a lambda function

I have a lambda function which is passed to a object and stored as a variable:
f = lambda x: x.method_foo()
I want to determine the name of method called on the variable x as a string. So I want
method_foo
saved as a string.
Any help appreciated.
You could access the lambda's code object with func_code, and access the code's local names with co_names.
>>> f = lambda x: x.method_foo
>>> f.func_code.co_names
('method_foo',)
>>> f.func_code.co_names[0]
'method_foo'
This is a bit "crazy", but you can use pass a Mock to f and get the method that was added to the mock after calling the function:
>>> from mock import Mock
>>> f = lambda x: x.method_foo
>>> m = Mock()
>>> old_methods = dir(m)
>>> f(m)
<Mock name='mock.method_foo' id='4517582608'>
>>> new_methods = dir(m)
>>> next(method for method in new_methods if method not in old_methods)
'method_foo'

Better way to call a chain of functions in python?

I have a chain of operations which needs to occur one after the other and each depends on the previous function's output.
Like this:
out1 = function1(initial_input)
out2 = function2(out1)
out3 = function3(out2)
out4 = function4(out3)
and so on about 10 times. It looks a little ugly in the code.
What is the best way to write it? Is there someway to handle it using some functional programming magic? Is there a better way to call and execute this function chain?
You can use functools.reduce:
out = functools.reduce(lambda x, y : y(x), [f1, f2, f3, f4], initial_value)
Quoting functools.reduce documentation:
Apply a function of two arguments cumulatively to the items of a sequence,
from left to right, so as to reduce the sequence to a single value.
For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
((((1+2)+3)+4)+5). If initial is present, it is placed before the items
of the sequence in the calculation, and serves as a default when the
sequence is empty.
Here, we use the fact that functions can be treated as any variable in Python, and an anonymous functions which simply does "apply x to function y".
This "reduce" operation is part of a very general pattern which have been applied successfully to parallelize tasks (see http://en.wikipedia.org/wiki/MapReduce).
Use a loop:
out = initial_input
for func in [function1, function2, function3, function4]:
out = func(out)
To propagate functional programming a bit:
In [1]: compose = lambda f, g: lambda arg: f(g(arg))
In [2]: from functools import reduce
In [3]: funcs = [lambda x:x+1, lambda x:x*2]
In [4]: f = reduce(compose, funcs)
In [5]: f(1)
Out[5]: 3
In [6]: f(3)
Out[6]: 7
You can pass the return values directly to the next function:
out4 = function4(function3(function2(function1(initial_input))))
But this isn't necessarily better, and is perhaps less readable.

How do you apply a list of lambda functions to a single element using an iterator?

I want to apply a list of lambda functions to a single element using an iterable that has to be created with yield.
The list of lambda functions would have something like:
[<function <lambda> at 0x1d310c8>, <function <lambda> at 0x1d355f0>]
And I want to apply every function, from left to right , to a single element using yield to construct an iterable to iterate the list
def apply_all(functions, item):
for f in functions:
yield f(item)
Example usage:
functions = [type, id, hex]
for result in apply_all(functions, 55):
print result
gives
<type 'int'>
20326112
0x37
Give this a shot:
def lambda_apply(unnamed_funcs, element):
for unnamed in unnamed_funcs:
yield unnamed(element)
>>> l = [lambda x: x**2, lambda x: 2*x]
>>> el = 5
>>> for y in lambda_apply(l, el):
... print y
...
25
10
Note that this works not only for a list of unnamed functions, but any list of functions of arity 1. This is because all functions, named or not, are first class objects in python. You can store them in a list, and use them later, as demonstrated above.
The answer could be formulated as
import numpy as np
def apply_funcs( funcs, val ):
for func in funcs:
yield func(val)
my_funcs = [lambda x: np.cos(x), np.sin, np.tan]
my_val = 0.1
for res in apply_funcs( my_funcs, my_val ):
print res
where the apply_funcs function does the trick and the rest is just for demonstration purposes.
Do you necessarily need a yield statement?
Because there is another way to create generator: to use ().
applied_it = (f(item) for f in functions)
def apply(value, lambda_list):
for function in lambda_list:
yield (function(value))

Categories