Python фильтрует список, чтобы только оставить объекты, которые происходят однажды

Вдобавок к тому, что некоторые другие сказали от моего понимания.NET и Java лучше в выделении памяти. Например, они могут уплотнить память, поскольку она фрагментируется, в то время как C++ не может (исходно, но она может при использовании умного сборщика "мусора").

6
задан Daniel Farrell 16 August 2009 в 22:13
поделиться

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
8
ответ дан 8 December 2019 в 02:16
поделиться

Вам понадобятся два цикла (или, что эквивалентно, цикл и listcomp, как показано ниже), но не вложенные:

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

Это решение предполагает, что элементы списка хэшируемые , то есть что они могут использоваться в качестве индексов в словах, членах наборов и т. Д.

OP указывает, что они заботятся об ИДЕНТИЧНОСТИ объекта и не ЗНАЧЕНИЕ (так, например, два подсписка, каждый из которых имеет значение [1,2,3 , которые равны, но могут не быть идентичными, не будут считаться дубликатами). Если это действительно так, то этот код можно использовать, просто замените d [x] на d [id (x)] в обоих случаях, и он будет работать для ЛЮБЫХ типов объектов в list L.

Изменяемые объекты (списки, словари, наборы и т. д.) обычно не хешируются и поэтому не могут использоваться подобным образом. Пользовательские объекты по умолчанию хешируются (с hash (x) == id (x) ), если их класс не определяет специальные методы сравнения ( __ eq __ ,

12
ответ дан 8 December 2019 в 02:16
поделиться
[x for x in the_list if the_list.count(x)==1]

Хотя это все еще скрытый за кадром вложенный цикл.

9
ответ дан 8 December 2019 в 02:16
поделиться
>>> l = [0,1,1,2,2]
>>> [x for x in l if l.count(x) is 1]
[0]
3
ответ дан 8 December 2019 в 02:16
поделиться
>>> l = [0,1,1,2,2]
>>> [x for x in l if l.count(x) == 1]
[0]
1
ответ дан 8 December 2019 в 02:16
поделиться
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 )
3
ответ дан 8 December 2019 в 02:16
поделиться

В том же духе, что и в решении Алекса, вы можете использовать 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
ответ дан 8 December 2019 в 02:16
поделиться

Я думаю, что фактическое время довольно интересно:

Ответ Алекса:

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), чтобы продемонстрировать, почему важна компетентность; -)

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

Роберто + сортировка:

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's:

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

Мне нравится последний, умный и быстрый; -)

2
ответ дан 8 December 2019 в 02:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: