Python assignment as function

Assignment inside lambda expression in Python

I have a list of objects and I want to remove all objects that are empty except for one, using filter and a lambda expression. For example if the input is:

[Object(name=""), Object(name="fake_name"), Object(name="")] 
[Object(name=""), Object(name="fake_name")] 
flag = True input = [Object(name=""), Object(name="fake_name"), Object(name="")] output = filter( (lambda o: [flag or bool(o.name), flag = flag and bool(o.name)][0]), input ) 

No. But you don’t need this. Actually I think it would be a pretty obscure way to achive this even if it worked.

I wanted to use lambda just so it would be a really compact solution. I remember in OCaml I could chain print statements before the return expression, thought this could be replicated in Python

It is quite painful to be in the flow of developing a chained pipeilne then realize: «oh I want to create a temp var to make the flow more clear» or «i want to log this intermediate step» : and then you have to jump somewhere else to create a function to do it: and name that function and keep track of it — even though it’s used in just one place .

13 Answers 13

The assignment expression operator := added in Python 3.8 supports assignment inside of lambda expressions. This operator can only appear within a parenthesized (. ) , bracketed [. ] , or braced <. >expression for syntactic reasons. For example, we will be able to write the following:

import sys say_hello = lambda: ( message := "Hello world", sys.stdout.write(message + "\n") )[-1] say_hello() 

In Python 2, it was possible to perform local assignments as a side effect of list comprehensions.

import sys say_hello = lambda: ( [None for message in ["Hello world"]], sys.stdout.write(message + "\n") )[-1] say_hello() 

However, it’s not possible to use either of these in your example because your variable flag is in an outer scope, not the lambda ‘s scope. This doesn’t have to do with lambda , it’s the general behaviour in Python 2. Python 3 lets you get around this with the nonlocal keyword inside of def s, but nonlocal can’t be used inside lambda s.

Читайте также:  Java разница между localdatetime

There’s a workaround (see below), but while we’re on the topic.

In some cases you can use this to do everything inside of a lambda :

(lambda: [ ['def' for sys in [__import__('sys')] for math in [__import__('math')] for sub in [lambda *vals: None] for fun in [lambda *vals: vals[-1]] for echo in [lambda *vals: sub( sys.stdout.write(u" ".join(map(unicode, vals)) + u"\n"))] for Cylinder in [type('Cylinder', (object,), dict( __init__ = lambda self, radius, height: sub( setattr(self, 'radius', radius), setattr(self, 'height', height)), volume = property(lambda self: fun( ['def' for top_area in [math.pi * self.radius ** 2]], self.height * top_area))))] for main in [lambda: sub( ['loop' for factor in [1, 2, 3] if sub( ['def' for my_radius, my_height in [[10 * factor, 20 * factor]] for my_cylinder in [Cylinder(my_radius, my_height)]], echo(u"A cylinder with a radius of %.1fcm and a height " u"of %.1fcm has a volume of %.1fcm³." % (my_radius, my_height, my_cylinder.volume)))])]], main()])() 

A cylinder with a radius of 10.0cm and a height of 20.0cm has a volume of 6283.2cm³.
A cylinder with a radius of 20.0cm and a height of 40.0cm has a volume of 50265.5cm³.
A cylinder with a radius of 30.0cm and a height of 60.0cm has a volume of 169646.0cm³.

. back to your original example: though you can’t perform assignments to the flag variable in the outer scope, you can use functions to modify the previously-assigned value.

For example, flag could be an object whose .value we set using setattr :

flag = Object(value=True) input = [Object(name=''), Object(name='fake_name'), Object(name='')] output = filter(lambda o: [ flag.value or bool(o.name), setattr(flag, 'value', flag.value and bool(o.name)) ][0], input) 
[Object(name=''), Object(name='fake_name')] 

If we wanted to fit the above theme, we could use a list comprehension instead of setattr :

 [None for flag.value in [bool(o.name)]] 

But really, in serious code you should always use a regular function definition instead of a lambda if you’re going to be doing outer assignment.

flag = Object(value=True) def not_empty_except_first(o): result = flag.value or bool(o.name) flag.value = flag.value and bool(o.name) return result input = [Object(name=""), Object(name="fake_name"), Object(name="")] output = filter(not_empty_except_first, input) 

Источник

Assignment with function or method

Is there any way to assign a value to a variable, in python, with a function or method? I am writing a Scheme interpreter and the process would be greatly simplified if I could. This can be done for basic logic and math with the operator module like so:

>>> operator.assign(a, 5) >>> print(a) 5 

Basic variable assignment works like x = operator.add(2, 3) , but I assume that is not what you meant. Can you provide an example of a line of code with the expected output?

That assign can’t be implemented since Python doesn’t support call-by-reference. It’s not obvious how this would simplify anything, though. Do you have an example?

Basically I have a bunch of symbols linked to functions in a dictionary. If the program reads a + then it looks for it in the dictionary and feeds it two arguments. I would like to do the same thing for define for variable definitions.

@ayNONE Use the same mechanism – mapping names to values in a dictionary. Don’t involve Python variables in it.

4 Answers 4

The need for this functionality may be a hint that the program design needs rethinking.

You did not provide any details, but a separate namespace might be required to prevent name clashes.

For example, all variables assignable this way could be stored in a container of some kind maybe even in a separate module. No «tricks» would be required.

After these warnings, here is an example. It can (re)assing any name in the current module.

import sys this_module = sys.modules[__name__] def assign(name, value): setattr(this_module, name, value) a = 1000 assign('b', a + 3) print(b) # 1003 

Источник

Python def function assignment with lambda

So lambda takes the positional argument x right? And by assigning the function object writer() to ‘who’ I somehow have access to lambda?

Try typing one of these into the interactive interpreter to get a bit of insight into what’s happening: writer() (don’t assign it to anything, thus forcing what it returns to be printed to the console), or who .

read up on closures and functions as objects. also, more to your point, lambda just defines a function. when you return it, you can use it.

1 Answer 1

You are returning a function, the outer function closes over creating a closure with the __closure__ method so there is still a reference to title so it can be used in the inner function:

def writer(): title = "Mr" name = (lambda x: title + ' ' + x) return name wr = writer() print(wr.__closure__) print(wr("foo")) def writer(): title = "Mr" def name(x): return title + ' ' + x return name wr = writer() print(wr.__closure__) print(wr("foo")) (,) Mr foo (,) Mr foo 

If you take the following function factory that takes an input e which is an exponent you want to raise x in the inner function to:

def exp(e): def rse_to(x): return x ** e return rse_to square = exp(2) print(square(2)) # call inner function, returns 2 ** 2 

In your first function, you don’t take any argument so you cannot pass any args. You are simply returning the lambda function which takes one positional argument.

def writer(): title = "Mr" name = (lambda x: title + ' ' + x) return name wr = writer() print(wr) . at 0x7f60e699dbf8> 

What you are trying to do by passing an arg to writer is no different to defining a normal function which takes no args and try to pass one to it.

In [2]: def foo(): . print("I take no args") . In [3]: foo() I take no args In [4]: foo(2) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) in () ----> 1 foo(2) TypeError: foo() takes 0 positional arguments but 1 was given 

Источник

Оцените статью