开发者

Lambda function and 0

开发者 https://www.devze.com 2023-02-13 04:12 出处:网络
I want to make a function that changes each elements in list with lambda function. a = [1,5,2,4] def func1(list,func2):

I want to make a function that changes each elements in list with lambda function.

a = [1,5,2,4]

def func1(list,func2):
    for x in range(len(list)):
        list[x] = func2(list[x])

func1(a,lambda x: x>3 and 10 or x)
print a

The result is [1,10,2,10]

This is OK. But I change '10' to '0'

func1(a,lambda x: x>3 and 0 or x)

The result is 开发者_如何学Go[1,5,2,4]

Why doesn't the result be [1,0,2,0]?

I'm sorry that I'm poor at English.


The problem you have is that 0 is being evaluated as False which means that using the and-or trick as a conditional expression is failing.

Python 2.5 introduced "proper" conditional expressions of the form:

x = true_value if condition else false_value

So you can replace:

lambda x: x>3 and 0 or x

with:

lambda x: 0 if x > 3 else x

Also, you could use the map function to replace func1 if you're not bothered about updating the list in place:

a = map(lambda x: 0 if x > 3 else x,a)
print a

If you do want to modify the list in place you can use the enumerate function to simplify your code a little:

def func1(list,func2):
    for i,x in enumerate(list):
        list[i] = func2(x)


bool(0) -> False

bool(10) -> True


a and b or c

is equivalent (nearly, since your case proves it is not) to

b if a else c

So:

a = [1,5,2,4]

def func1(li,func2):
    for x,el in enumerate(li):
        li[x] = func2(el)

func1(a,lambda x: 0 if x>3 else x)
print a

Remark:

  • name list for a user's object is not good

  • use of iterate()

By the way, did you notice that you are changing in a function the value of an object external to the function ?

u = 102

def f(x):
    x = 90

print "u==",u

result

u== 102

In your code, a is changed because it is a mutable object

In common case, a function has a return. Yours has not, because you change a mutable object.


x>3 and 0 or x always returns x because 0 is False.

Replace it with:

(x > 3 and [0] or [x])[0]

to get:

func1(a,lambda x: (x>3 and [0] or [x])[0])

Result:

[1, 0, 2, 0]

How it works:

  1. The real return value is put into a single element list.
    Any non-empty list is True, so the and or works.
  2. Then use [0] to get the value back out.


You could turn it around:

func1(a,lambda x: x<=3 and x or 0)

(untested)

0

精彩评论

暂无评论...
验证码 换一张
取 消