使用 lambda 函数更改属性值

pyt*_*dev 6 python lambda

我可以使用 lambda 函数循环遍历类对象列表并更改属性值(对于所有对象或满足特定条件的对象)?

class Student(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age

student1 = Student('StudOne',18)
student2 = Student('StudTwo',20)
student3 = Student('StudThree',29)
students = [student1,student2,student3]

new_list_of_students = map(lambda student:student.age+=3,students)
Run Code Online (Sandbox Code Playgroud)

pok*_*oke 5

不幸的是,这是不可能的,因为lambda主体只允许简单的表达式,而 astudent.age += 3语句。所以你不能在那里使用 lambda。但是,您仍然可以使用地图解决方案:

def incrementAge (student):
    student.age += 3
    return student

students2 = map(incrementAge, students)
Run Code Online (Sandbox Code Playgroud)

请注意,students2它将包含相同的学生students,因此您实际上不需要捕获输出(或从 返回某些内容incrementAge)。另请注意,在 Python 3 中,map返回一个需要首先迭代的生成器。你可以调用list()它来做到这一点:list(map(…))

最后,对此更好的解决方案是使用简单的循环。这样,您就不会产生需要函数或创建重复学生列表的开销,而且您的意图也会非常明确:

for student in students:
    student.age += 3
Run Code Online (Sandbox Code Playgroud)


小智 5

Using a simple for-loop to retrieve the students to update the age for each is good enough like others said, but if you still want to use a lambda to update the values, you may need to leverage the exec() function:

_ = list(map(lambda student: exec("student.age+=3"), students))
for _ in students: print(_.age)
Run Code Online (Sandbox Code Playgroud)

Output:

21 23 32
Run Code Online (Sandbox Code Playgroud)

In this case, what actually does the updating is the exec(), and the map() just yields None. So the returned result makes no sense and I put a _ to clarify this. A more concise form would be this:

list(map(lambda _: exec("_.age+=3"), students))
Run Code Online (Sandbox Code Playgroud)

Besides, if only considering what you want to do, you don't need to use a map() at all (probably more confusing though):

[(lambda _: exec("_.age += 3"))(_) for _ in students]
Run Code Online (Sandbox Code Playgroud)

Furthermore, a lambda can be discarded either:

[exec("_.age += 3") for _ in students]
Run Code Online (Sandbox Code Playgroud)

As you can see, no "trick" codes above seem more concise than what other answers post:

for s in students:
    s.age += 3
Run Code Online (Sandbox Code Playgroud)

So maybe the so-called "one-liner" is useful just when it comes to having fun... :)


Ned*_*der 3

Lambda 函数只能包含表达式,不能包含语句。Python 中的赋值是一个语句。Lambda 不能执行赋值操作。此外,作业语句不会计算其值,因此您的地图不会生成学生列表。

你要这个:

for student in students:
    student.age += 3
Run Code Online (Sandbox Code Playgroud)

这不会给你一个新的列表,它会修改旧的列表,但你的旧列表无论如何都会被修改,你没有做任何事情来产生新的学生。