过滤集合的最Pythonic方式是什么?

29

我有一个由替代元素组成的列表,我想做两件事:

  1. 删除重复项
  2. 根据特定标准删除所有元素,确切地说,我想删除大于某个值的所有元素。

我认为我可以使用过滤器来实现第2步,然后使用集合来实现第1步

list(set(filter(lambda x:x<C, l)))

有没有更好/更符合Python风格/更高效的方法?


我的意思是,集合是无序的,因此如果您想保持一些顺序,使用集合可能会让您感到很失望。 - Padraic Cunningham
实际上在我的情况下,顺序并不重要。 - Meni
3个回答

47

使用列表推导式或许更符合Python风格。


filtered = [x for x in set(lst) if x < C]

1
但是在这种理解方式下,set(lst) 不会被计算每一个 x 吗? - Meni
5
绝对不是这样。for x in set(lst)会在将列表转换为集合后创建一个迭代器,然后列表解析会遍历它并在x < C时存储值。 - Delgan
1
使用列表推导而不是集合推导有什么原因吗? - Meni
1
@Meni 我认为将预期输出设置为列表更有意义,而且比使用 list() 包装集合理解起来更清晰。然而,这并没有太大的区别,由你来决定。 - Delgan

9

最好的两种方法是使用过滤器:

new_list = list(set(filter(lambda x:x<C, l)))

或者使用集合推导式(很多人认为更具Python风格,甚至更高效):
list({x for x in l if x < C})

但我猜,如果你熟悉过滤器,你可以直接使用它。


1
你可以使用集合推导式来替代将列表推导式转换为集合。 - R Nar
谢谢,我不知道当时在想什么。 - Y2H
如果我最终要将其转换为列表,使用集合推导是否比列表推导更好? - Meni
这肯定更短更高效。在编译方面,我相信很多人会假装知道哪个更好,但最终的差异实际上是无法察觉的。 - Y2H

8

在我看来,尽可能使用集合操作(维恩图)过滤集合是最具Python特色的方式:

A = {0, 1, 4, 5, 8}; 
B = {2, 1, 3, 4, 6}; 

print("Union :", A | B) 

print("Intersection :", A & B) 

print("Difference :", A - B) 

print("Symmetric difference :", A ^ B) 

当你想从集合A中移除值5时,只需键入:

A - {5,}

在这个问题中,如果您需要过滤大于C的值,您只需键入“包含检查”运算符“in”,在Python代码中执行sets.contains()魔术方法(魔术方法不应该直接调用,这就是为什么使用“in”的原因):

{x for x in l if x > C}

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