从对象列表中删除对象的最简单方法是什么?

6

我正在尝试从列表中移除一个项目。通常这很显然,但问题在于这些项目是对象,我想通过它们的某个属性来删除它们。

有比我下面展示的更优雅的方法吗?

class Item:
    def __init__(self, name, color):
        self.name = name
        self.type = type

if __name__ == "__main__":
    myList = []
    myList.append(Item("item1", "green"))
    myList.append(Item("item2", "blue"))

    # Try to remove object with name "item2"
    index = None
    for i, val in enumerate(myList):
        if val.name == "item2"
            del myList[i]

你总是可以使用 repr dunder 方法。 - Julian Camilleri
你也可以使用像 map(attrgetter('my_attr'), my_list) 这样的语法,attrgetter 可在内置库 operator 中找到。 - Julian Camilleri
2个回答

5
你也可以使用内置方法 filter(function, iterable)

filter() 对每个元素应用一个函数,如果函数计算结果为True,则该元素在生成器中。如果函数计算结果为False,则跳过该元素。

filter(..) 的结果是生成器,因此需要将其放入列表中(或者如果只需要一次使用生成器结果,则使用生成器结果)。

演示:

class Item:
    def __init__(self, name, num):
        self.name = name
        self.num = num

    def __repr__(self):
        return f"({self.name} - {self.num})"


if __name__ == "__main__":
    myList = []
    for n in range(0,20):
        myList.append(Item(str(n), n))

    newList1 = list( filter(lambda x: x.num % 3 == 0, myList) ) 

print(myList)

print(newList1) 

输出:
# input to filter
[  (0 - 0),   (1 - 1),   (2 - 2),   (3 - 3),   (4 - 4),   (5 - 5),   (6 - 6), (7 - 7),   
   (8 - 8),   (9 - 9), (10 - 10), (11 - 11), (12 - 12), (13 - 13), (14 - 14), (15 - 15),
 (16 - 16), (17 - 17), (18 - 18), (19 - 19)] 

# result of filter
[(0 - 0), (3 - 3), (6 - 6), (9 - 9), (12 - 12), (15 - 15), (18 - 18)]

很好地解释了。但是也许提供一个处理OP所描述的确切情况的示例会更好(即:删除名称为“item2”的对象)。 - Floella
1
@floella - wyw = list( filter(lambda i: i.name != 'item2', [Item("item1","green"), Item("item2","blue"), ] ) ) 这样应该就可以了。我认为最好使用列表表达式来解决问题。 - Patrick Artner

3
这里有一个超级简单的方法:
[x for x in myList if x.name != 'item2']

也就是说,只需创建一个包含所需项目的新列表即可。如果需要,可以将其重新分配给myList


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接