我是否可以使用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)
答案 0 :(得分:3)
不幸的是,这是不可能的,因为body of a lambda只允许simple expressions而student.age += 3
是statement。所以你不能在那里使用lambda。但是,你仍然可以使用地图解决方案:
def incrementAge (student):
student.age += 3
return student
students2 = map(incrementAge, students)
请注意,students2
将包含与students
相同的学生,因此您不需要捕获输出(或从incrementAge
返回内容)。另请注意,在Python 3中,map
返回一个您需要首先迭代的生成器。您可以在其上调用list()
来执行此操作:list(map(…))
。
最后,更好的解决方案是使用简单的循环。这样,您就没有需要功能或创建重复学生列表的开销,您也可以非常明确地表达意图:
for student in students:
student.age += 3
答案 1 :(得分:2)
使用简单的for循环来检索6
来更新每个students
就像其他人所说的一样好,但是如果您仍然想使用age
来更新{值,则可能需要利用lambda
函数:
exec()
输出:
_ = list(map(lambda student: exec("student.age+=3"), students))
for _ in students: print(_.age)
在这种情况下,实际上进行的更新是21 23 32
,而exec()
仅产生map()
。因此,返回的结果没有任何意义,因此我添加了None
来阐明这一点。更为简洁的形式是:
_
此外,如果仅考虑要执行的操作,则根本不需要使用list(map(lambda _: exec("_.age+=3"), students))
(不过可能会更令人困惑):
map()
此外,[(lambda _: exec("_.age += 3"))(_) for _ in students]
可以被丢弃:
lambda
如您所见,上面没有“技巧”代码似乎比其他答案更简洁:
[exec("_.age += 3") for _ in students]
所以也许所谓的“单线”在获得乐趣时很有用... :)
答案 2 :(得分:1)
Lambda函数只能包含表达式,而不能包含语句。 Python中的赋值是一种陈述。 Lambdas无法完成任务。此外,赋值语句不会计算其值,因此您的地图不会生成学生列表。
你想要这个:
for student in students:
student.age += 3
这不会给你一个新列表,它会修改旧列表,但无论如何你的旧列表都会被修改,你没有做任何事来产生新学生。
答案 3 :(得分:1)
您可以使用setattr
,这会将更改应用于对象。一个很大的好处是你可以继续使用相同的列表。
map(lambda s: setattr(s, 'age', s.age + 3), students)
来自文档:
等效于:
for s in students:
s.age += 3
上述方法不会返回新列表;而是返回None
(setattr
的返回值)。添加or
与数组中所需对象的比较(在本例中为s
)将会对此进行修改。
new_students = map(lambda s: setattr(s, 'age', s.age + 3) or s, students)
比较相当于None or s
,它总是会产生后者。另请注意,新列表与旧列表相同。
答案 4 :(得分:0)
问:“我可以使用lambda函数循环遍历类对象列表并更改属性值”
答:是的......但你不应该。它的编码风格很差,效率低下,而且只适用于代码高尔夫等
你应该像其他两个答案一样写出来。
......但如果你真的想......
new_list_of_students = [(lambda student:(setattr(student, 'age', student.age+3),
student))(s)[1] for s in students]
print [student.age for student in new_list_of_students]
打印:
[21, 23, 32]
......甚至:
from operator import itemgetter
new_list_of_students = map(itemgetter(1),map(lambda student:(setattr(student,
'age', student.age+3), student),students))
print [student.age for student in new_list_of_students]
[输出相同]