Python过滤一个列表,只留下发生在

2024-03-29 09:15:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我想过滤这个列表

l=[0,1,1,2,2]

只有离开

[0]。

我正努力用一种“pythonic”的方式来实现它:o)没有嵌套循环是否可能?


Tags: 列表方式pythonic嵌套循环
3条回答

下面是另一种面向词典的方法:

l = [0, 1, 1, 2, 2]
d = {}
for i in l: d[i] = i in d

[k for k in d if not d[k]]  # unordered, loop over the dictionary
[k for k in l if not d[k]]  # ordered, loop over the original list
[x for x in the_list if the_list.count(x)==1]

尽管这仍然是幕后的一个嵌套循环。

您需要两个循环(或等效于一个循环和一个listcomp,如下所示),但不需要嵌套循环:

import collections
d = collections.defaultdict(int)
for x in L: d[x] += 1
L[:] = [x for x in L if d[x] == 1]

此解决方案假设列表项是可散列的,即它们可用作dict、集合成员等的索引

OP表示它们关心的是对象标识,而不是值(例如,两个子列表都值[1,2,3,它们相等但可能不相同,将不被视为重复项)。如果确实如此,那么这段代码是可用的,只需在两个实例中将d[x]替换为d[id(x)],它将适用于列表L中的任何类型的对象

可变对象(列表、dict、set,…)通常不可哈希,因此不能以这种方式使用。默认情况下,用户定义的对象是可散列的(使用hash(x) == id(x)),除非它们的类定义了比较特殊方法(__eq____cmp__,…),在这种情况下,它们是可散列的,前提是它们的类还定义了__hash__方法。

如果list L的项不可散列,但对于不等式来说是可比较的(因此是可排序的),并且您不关心它们在列表中的顺序,那么您可以通过首先对列表进行排序,然后应用itertools.groupby来及时执行任务O(N log N)(几乎不是另一个答案建议的那样)。

当您关心列表的原始顺序时(制作一个已排序的副本,并在第二个循环中借助于bisect——同样是O(N logn)但稍慢一点的帮助,检查其上的重复项),以及处理其唯一可应用属性的对象时,其他方法(性能逐渐降低,通用性增强)可以处理不可更改的排序它们在平等性上是可比的(在这种最大的一般情况下,无法避免可怕的O(N**2)性能)。

如果操作程序能说明哪种情况适用于他的特定问题,我将很乐意提供帮助(特别是,如果他中的对象是散列的,那么我上面已经给出的代码就足够了;-)。

相关问题 更多 >