You need to capture the current values of loop variables when the lambda is created. Otherwise the function will read the value of those variables in the scope of its creation at the time it is invoked.
It can be done via argument defaults:
part = lambda theta,phi, x=x, y=y, z=z, k=k: (N.cos(theta)**(0.5))*N.sin(theta)*N.exp(-1j*k*(x*N.sin(theta)*N.cos(phi) + y*N.sin(theta)*N.sin(phi) - z*N.cos(theta)))
Answer from Dan D. on Stack OverflowThere are several different answers I can give here, from your specific question to more general concerns. So from most specific to most general:
Q. Can you put multiple statements in a lambda?
A. No. But you don't actually need to use a lambda. You can put the statements in a def instead. i.e.:
def second_lowest(l):
l.sort()
return l[1]
map(second_lowest, lst)
Q. Can you get the second lowest item from a lambda by sorting the list?
A. Yes. As alex's answer points out, sorted() is a version of sort that creates a new list, rather than sorting in-place, and can be chained. Note that this is probably what you should be using - it's bad practice for your map to have side effects on the original list.
Q. How should I get the second lowest item from each list in a sequence of lists?
A. sorted(l)[1] is not actually the best way for this. It has O(N log(N)) complexity, while an O(n) solution exists. This can be found in the heapq module.
>>> import heapq
>>> l = [5,2,6,8,3,5]
>>> heapq.nsmallest(l, 2)
[2, 3]
So just use:
map(lambda x: heapq.nsmallest(x,2)[1], list_of_lists)
It's also usually considered clearer to use a list comprehension, which avoids the lambda altogether:
[heapq.nsmallest(x,2)[1] for x in list_of_lists]
Putting the expressions in a list may simulate multiple expressions:
E.g.:
lambda x: [f1(x), f2(x), f3(x), x+1]
This will not work with statements.
Use if else statement in a lambda:
print(list(map(lambda x: x*2 if type(x)==int else x.replace('r','*'),lst)))
Output:
[8, 10, 12, '*e*', 't*', 100, 120]
Even better, use isinstance:
print(list(map(lambda x: x*2 if isinstance(x,int) else x.replace('r','*'),lst)))
Prefer isinstance in place of type
lst = [4,5,6,'rer', 'tr',50,60]
lst = list(map(lambda x: x*2 if isinstance(x, int) else x.replace('r', '*'), lst))
lst
[8, 10, 12, '*e*', 't*', 100, 120]