python - loop for inside lambda - Stack Overflow
Python - Iterating through a list -Lambda - Stack Overflow
python - Lambda function in list comprehensions - Stack Overflow
python - Creating lambda inside a loop - Stack Overflow
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 of Nones.
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")
ids = [1600,1500,1800,1900,1700]
alist=ids
sorted_ids=[]
def last_four(alist):
for element in alist:
values=str(element)
sorted_ids.append(values[1:4])
return sorted(sorted_ids)
print(last_four(alist))
results in :

for your second question here is the code
last_four = list(map(lambda element: str(element)[1:4], alist))
print(sorted(last_four))
Your code seems to works well already.
If you want to use lambda, you can write your code something like this. (Which is same with the answer posted, only the difference is that you can immediately use sorted function without deliberately converting a map object into a list object.)
def main():
ids = [1600, 1500, 1800, 1900, 1700]
alist = ids
sorted_last_four = sorted(map(lambda element: str(element)[1:4], alist))
print(sorted_last_four)
if __name__ == '__main__':
main()
If you are not familiar with using lambda, or you want to get some intuition of how to use lambda and sorted functions together, you can read this answer posted.
Good luck.
The first one creates a single lambda function and calls it ten times.
The second one doesn't call the function. It creates 10 different lambda functions. It puts all of those in a list. To make it equivalent to the first you need:
[(lambda x: x*x)(x) for x in range(10)]
Or better yet:
[x*x for x in range(10)]
This question touches a very stinking part of the "famous" and "obvious" Python syntax - what takes precedence, the lambda, or the for of list comprehension.
I don't think the purpose of the OP was to generate a list of squares from 0 to 9. If that was the case, we could give even more solutions:
squares = []
for x in range(10): squares.append(x*x)
- this is the good ol' way of imperative syntax.
But it's not the point. The point is W(hy)TF is this ambiguous expression so counter-intuitive? And I have an idiotic case for you at the end, so don't dismiss my answer too early (I had it on a job interview).
So, the OP's comprehension returned a list of lambdas:
[(lambda x: x*x) for x in range(10)]
This is of course just 10 different copies of the squaring function, see:
>>> [lambda x: x*x for _ in range(3)]
[<function <lambda> at 0x00000000023AD438>, <function <lambda> at 0x00000000023AD4A8>, <function <lambda> at 0x00000000023AD3C8>]
Note the memory addresses of the lambdas - they are all different!
You could of course have a more "optimal" (haha) version of this expression:
>>> [lambda x: x*x] * 3
[<function <lambda> at 0x00000000023AD2E8>, <function <lambda> at 0x00000000023AD2E8>, <function <lambda> at 0x00000000023AD2E8>]
See? 3 time the same lambda.
Please note, that I used _ as the for variable. It has nothing to do with the x in the lambda (it is overshadowed lexically!). Get it?
I'm leaving out the discussion, why the syntax precedence is not so, that it all meant:
[lambda x: (x*x for x in range(10))]
which could be: [[0, 1, 4, ..., 81]], or [(0, 1, 4, ..., 81)], or which I find most logical, this would be a list of 1 element - a generator returning the values. It is just not the case, the language doesn't work this way.
BUT What, If...
What if you DON'T overshadow the for variable, AND use it in your lambdas???
Well, then crap happens. Look at this:
[lambda x: x * i for i in range(4)]
this means of course:
[(lambda x: x * i) for i in range(4)]
BUT it DOESN'T mean:
[(lambda x: x * 0), (lambda x: x * 1), ... (lambda x: x * 3)]
This is just crazy!
The lambdas in the list comprehension are a closure over the scope of this comprehension. A lexical closure, so they refer to the i via reference, and not its value when they were evaluated!
So, this expression:
[(lambda x: x * i) for i in range(4)]
IS roughly EQUIVALENT to:
[(lambda x: x * 3), (lambda x: x * 3), ... (lambda x: x * 3)]
I'm sure we could see more here using a python decompiler (by which I mean e.g. the dis module), but for Python-VM-agnostic discussion this is enough.
So much for the job interview question.
Now, how to make a list of multiplier lambdas, which really multiply by consecutive integers? Well, similarly to the accepted answer, we need to break the direct tie to i by wrapping it in another lambda, which is getting called inside the list comprehension expression:
Before:
>>> a = [(lambda x: x * i) for i in (1, 2)]
>>> a1
2
>>> a0
2
After:
>>> a = [(lambda y: (lambda x: y * x))(i) for i in (1, 2)]
>>> a1
2
>>> a0
1
(I had the outer lambda variable also = i, but I decided this is the clearer solution - I introduced y so that we can all see which witch is which).
Edit 2019-08-30:
Following a suggestion by @josoler, which is also present in an answer by @sheridp - the value of the list comprehension "loop variable" can be "embedded" inside an object - the key is for it to be accessed at the right time. The section "After" above does it by wrapping it in another lambda and calling it immediately with the current value of i. Another way (a little bit easier to read - it produces no 'WAT' effect) is to store the value of i inside a partial object, and have the "inner" (original) lambda take it as an argument (passed supplied by the partial object at the time of the call), i.e.:
After 2:
>>> from functools import partial
>>> a = [partial(lambda y, x: y * x, i) for i in (1, 2)]
>>> a0, a1
(2, 4)
Great, but there is still a little twist for you! Let's say we wan't to make it easier on the code reader, and pass the factor by name (as a keyword argument to partial). Let's do some renaming:
After 2.5:
>>> a = [partial(lambda coef, x: coef * x, coef=i) for i in (1, 2)]
>>> a0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: <lambda>() got multiple values for argument 'coef'
WAT?
>>> a0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: <lambda>() missing 1 required positional argument: 'x'
Wait... We're changing the number of arguments by 1, and going from "too many" to "too few"?
Well, it's not a real WAT, when we pass coef to partial in this way, it becomes a keyword argument, so it must come after the positional x argument, like so:
After 3:
>>> a = [partial(lambda x, coef: coef * x, coef=i) for i in (1, 2)]
>>> a0, a1
(2, 4)
I would prefer the last version over the nested lambda, but to each their own...
Edit 2020-08-18:
Thanks to commenter dasWesen, I found out that this stuff is covered in the Python documentation: https://docs.python.org/3.4/faq/programming.html#why-do-lambdas-defined-in-a-loop-with-different-values-all-return-the-same-result - it deals with loops instead of list comprehensions, but the idea is the same - global or nonlocal variable access in the lambda function. There's even a solution - using default argument values (like for any function):
>>> a = [lambda x, coef=i: coef * x for i in (1, 2)]
>>> a0, a1
(2, 4)
This way the coef value is bound to the value of i at the time of function definition (see James Powell's talk "Top To Down, Left To Right", which also explains why mutable default values are shunned).
Use this line instead:
lambdas_list.append(lambda obj=obj: obj.some_var)
You either have to capture the variable using default assignments
lambdas_list = [ lambda i=o: i.some_var for o in obj_list ]
or, use closures to capture the variable
lambdas_list = [ (lambda a: lambda: a.some_var)(o) for o in obj_list ]
In both cases the key is to make sure each value in the obj_list list is assigned to a unique scope.
Your solution didn't work because the lexical variable obj is referenced from the parent scope (the for).
The default assignment worked because we reference i from the lambda scope. We use the default assignment to make "passing" the variable implicit by making it part of the lambda definition and therefore its scope.
The closure solution works because the variable "passing" is explicit, into the outer lambda which is immediately executed, thus creating the binding during the list comprehension and and returning the inner lambda which references that binding. So when the inner lambda actually executes it will be referencing the binding created in the outer lambda scope.
Hey all,
Can someone explain why when I run the below code:
arr = []
for n in range(1,5):
arr.append(lambda n: 5+n)
I can't run one of the functions in the array by simply calling arr[0]()with empty parenthesis?
it throws an error saying I need to pass one positional argument, n - but I'm passing it using for loop, am I not?
There is evidently something I'm missing.
What makes it worse to me is that ok, if I pass an argument, say I will call art[0](7) - that makes the n in my lambda and in for loop useless, because the value (of n) didn't get passed at all to that lambda n: definition...
Any help would be appreciated!
Lambdas are just another way of defining a function
def foo(x):
return x + x
is the same as
foo = lambda x: x + x
So let's start with a function to do what you want:
def first_missing(items, base):
for number in itertools.count():
text = base + '_' + str(number)
if text not in items:
return text
The first thing to note is that you can't use loops inside a lambda. So we'll need to rewrite this without a loop. Instead, we'll use recursion:
def first_missing(items, base, number = 0):
text = base + '_' + str(number)
if text not in items:
return text
else:
return first_missing(items, base, number + 1)
Now, we also can't use an if/else block in a lambda. But we can use a ternary expression:
def first_missing(items, base, number = 0):
text = base + '_' + str(number)
return text if text not in items else first_missing(items, base, number + 1)
We can't have local variables in a lambda, so we'll use a trick, default arguments:
def first_missing(items, base, number = 0):
def inner(text = base + '_' + str(number)):
return text if text not in items else first_missing(items, base, number + 1)
return inner()
At this point we can rewrite inner as a lambda:
def first_missing(items, base, number = 0):
inner = lambda text = base + '_' + str(number): text if text not in items else first_missing(items, base, number + 1)
return inner()
We can combine two lines to get rid of the inner local variable:
def first_missing(items, base, number = 0):
return (lambda text = base + '_' + str(number): text if text not in items else first_missing(items, base, number + 1))()
And at long last, we can make the whole thing into a lambda:
first_missing = lambda: items, base, number = 0: (lambda text = base + '_' + str(number): text if text not in items else first_missing(items, base, number + 1))()
Hopefully that gives you some insight into what you can do. But don't ever do it because, as you can tell, lambdas can make your code really hard to read.
There's no need to use a lambda in this case, a simple for loop will do:
my_test = 'test_name_dup'
testlist = ['test_name', 'test_name_dup','test_name_dup_1', 'test_name_dup_3']
for i in xrange(1, len(testlist)):
if my_test + '_' + str(i) not in testlist:
break
print my_test + '_' + str(i)
> test_name_dup_2
If you really, really want to use a lambda for this problem, you'll also have to learn about itertools, iterators, filters, etc. I'm gonna build on thg435's answer, writing it in a more idiomatic fashion and explaining it:
import itertools as it
iterator = it.dropwhile(
lambda n: '{0}_{1}'.format(my_test, n) in testlist,
it.count(1))
print my_test + '_' + str(iterator.next())
> test_name_dup_2
The key to understanding the above solution lies in the dropwhile() procedure. It takes two parameters: a predicate and an iterable, and returns an iterator that drops elements from the iterable as long as the predicate is true; afterwards, returns every element.
For the iterable, I'm passing count(1), an iterator that produces an infinite number of integers starting from 1.
Then dropwhile() starts to consume the integers until the predicate is false; this is a good opportunity for passing an in-line defined function - and here's our lambda. It receives each generated integer in turn, checking to see if the string test_name_dup_# is present in the list.
When the predicate returns false, dropwhile() returns and we can retrieve the value that made it stop by calling next() on it.
Hi! Just a simple question, I was wondering how to create a list of different lambda functions like so:
[(lambda x: x*i) for i in range(3)]
Ideally, this should return an output like this:
[lambda x: x*0, lambda x: x*1, lambda x: x*2]
However, the actual output is like so:
[lambda x: x*2, lambda x: x*2, lambda x: x*2]
How would I go about producing the desired output? Thanks!