我想过滤此列表,
l = [0,1,1,2,2]
只离开,
[0]。
我正在努力以'pythonic'的方式做到这一点:o)没有嵌套循环是否可能?
答案 0 :(得分:12)
你需要两个循环(或等效的循环和listcomp,如下所示),但不需要嵌套循环:
import collections
d = collections.defaultdict(int)
for x in L: d[x] += 1
L[:] = [x for x in L if d[x] == 1]
此解决方案假定列表项是 hashable ,即它们可用作dicts,集合成员等的索引。
OP表示他们关心对象IDENTITY而不是VALUE(因此,例如两个值相等但[1,2,3
的子列表相同但可能不相同的子列表不会被视为重复)。如果确实如此,则此代码可用,只需在两次出现中将d[x]
替换为d[id(x)]
,它将适用于列表L中的任何类型的对象。
可变对象(列表,字符串,集合......)通常不可清除,因此不能以这种方式使用。默认情况下,用户定义的对象是可以使用的(hash(x) == id(x)
),除非它们的类定义了比较特殊方法(__eq__
,__cmp__
,...),在这种情况下,它们只能是可以清除的如果他们的类也定义了__hash__
方法。
如果列表的项目不可清,但 可用于不等式(因此可排序),并且您不关心它们在列表中的顺序,您可以及时执行任务{ {1}}首先对列表进行排序,然后应用O(N log N)
(几乎但不完全按照另一个答案建议的方式)。
当你关心列表的原始顺序时,可以处理不可变的可排序的其他方法(制作一个已排序的副本,在第二个循环中,在{{1}的帮助下检查重复的顺序 - 也是O(N log N)但速度稍慢),并且对象的唯一适用属性是它们的相等性(无法避免最大程度上的可怕O(N ** 2)性能一般情况)。
如果OP可以澄清哪种情况适用于他的具体问题,我将很乐意提供帮助(特别是,如果他的物品是可以清洗的,我上面已经给出的代码应该足够了;-)。
答案 1 :(得分:9)
[x for x in the_list if the_list.count(x)==1]
虽然这仍然是幕后的嵌套循环。
答案 2 :(得分:8)
这是另一种面向字典的方式:
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
答案 3 :(得分:4)
与Alex的解决方案一样,您可以使用Counter / multiset(内置2.7,兼容2.5及以上的配方)来做同样的事情:
In [1]: from counter import Counter
In [2]: L = [0, 1, 1, 2, 2]
In [3]: multiset = Counter(L)
In [4]: [x for x in L if multiset[x] == 1]
Out[4]: [0]
答案 4 :(得分:3)
>>> l = [0,1,1,2,2]
>>> [x for x in l if l.count(x) is 1]
[0]
答案 5 :(得分:3)
l = [0,1,2,1,2]
def justonce( l ):
once = set()
more = set()
for x in l:
if x not in more:
if x in once:
more.add(x)
once.remove( x )
else:
once.add( x )
return once
print justonce( l )
答案 6 :(得分:1)
我认为实际时间很有意思:
亚历克斯回答:python -m timeit -s "l = range(1,1000,2) + range(1,1000,3); import collections" "d = collections.defaultdict(int)" "for x in l: d[x] += 1" "l[:] = [x for x in l if d[x] == 1]"
1000 loops, best of 3: 370 usec per loop
矿:
python -m timeit -s "l = range(1,1000,2) + range(1,1000,3)" "once = set()" "more = set()" "for x in l:" " if x not in more:" " if x in once:" " more.add(x)" " once.remove( x )" " else:" " once.add( x )"
1000 loops, best of 3: 275 usec per loop
sepp2k的O(n ** 2)版本,以证明为什么compexity很重要; - )
python -m timeit -s "l = range(1,1000,2) + range(1,1000,3)" "[x for x in l if l.count(x)==1]"
100 loops, best of 3: 16 msec per loop
Roberto's + sorted:
python -m timeit -s "l = range(1,1000,2) + range(1,1000,3); import itertools" "[elem[0] for elem in itertools.groupby(sorted(l)) if elem[1].next()== 0]"
1000 loops, best of 3: 316 usec per loop
mhawke的:
python -m timeit -s "l = range(1,1000,2) + range(1,1000,3)" "d = {}" "for i in l: d[i] = d.has_key(i)" "[k for k in d.keys() if not d[k]]"
1000 loops, best of 3: 251 usec per loop
我喜欢最后一个,聪明又快速; - )
答案 7 :(得分:1)
>>> l = [0,1,1,2,2]
>>> [x for x in l if l.count(x) == 1]
[0]
答案 8 :(得分:0)
类似的问题出现在编码问题上。我的解决方案不是最优雅,但它是我的第一个自我融合的解决方案,因此希望与大家分享!
testlist = [2,4,6,8,10,2,6,10]
def unique_elements(testlist):
final_list = []
for x in testlist:
if testlist.count(x)==1:
final_list.append(x)
else:
pass
print(final_list)
unique_elements(testlist)