Как сделать так, чтобы списки содержали только отдельные элементы в Python? [дубликат]



этот вопрос уже есть ответ здесь:



У меня есть список в Python, как я могу заставить его значения уникальны?

259   10  

10 ответов:

самое простое-преобразовать в набор, а затем обратно в список:

my_list = list(set(my_list))

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

измененные версии http://www.peterbe.com/plog/uniqifiers-benchmark

чтобы сохранить порядок:

def f(seq): # Order preserving
  ''' Modified version of Dave Kirby solution '''
  seen = set()
  return [x for x in seq if x not in seen and not seen.add(x)]

ОК, теперь, как это работает, потому что это немного сложно здесь if x not in seen and not seen.add(x):

In [1]: 0 not in [1,2,3] and not print('add')
add
Out[1]: True

почему он возвращает True? печать (и набор.добавить) ничего не возвращает:

In [3]: type(seen.add(10))
Out[3]: <type 'NoneType'>

и not None == True, но:

In [2]: 1 not in [1,2,3] and not print('add')
Out[2]: False

почему он печатает "добавить" в [1], но не в [2]? Смотрите False and print('add'), и не проверяет второй аргумент, потому что он уже знает ответ, и возвращает true, только если оба аргумента истинны.

более общая версия, более читаемая, основанная на генераторе, добавляет возможность преобразования значений с помощью функции:

def f(seq, idfun=None): # Order preserving
  return list(_f(seq, idfun))

def _f(seq, idfun=None):  
  ''' Originally proposed by Andrew Dalke '''
  seen = set()
  if idfun is None:
    for x in seq:
      if x not in seen:
        seen.add(x)
        yield x
  else:
    for x in seq:
      x = idfun(x)
      if x not in seen:
        seen.add(x)
        yield x

без порядка (это быстрее):

def f(seq): # Not order preserving
  return list(set(seq))

ОДН-вкладыш и сохраняет заказ

list(OrderedDict.fromkeys([2,1,1,3]))

хотя вам понадобится

from collections import OrderedDict

чтобы сохранить порядок:

l = [1, 1, 2, 2, 3]
result = list()
map(lambda x: not x in result and result.append(x), l)
result
# [1, 2, 3]

позвольте мне объяснить вам на примере:

Если у вас есть список Python

>>> randomList = ["a","f", "b", "c", "d", "a", "c", "e", "d", "f", "e"]

и вы хотите удалить дубликаты из него.

>>> uniqueList = []

>>> for letter in randomList:
    if letter not in uniqueList:
        uniqueList.append(letter)

>>> uniqueList
['a', 'f', 'b', 'c', 'd', 'e']

Это, как вы можете удалить дубликаты из списка.

как о списочные словарь?

>>> mylist = [3, 2, 1, 3, 4, 4, 4, 5, 5, 3]

>>> {x:1 for x in mylist}.keys()
[1, 2, 3, 4, 5]

EDIT К комментарию @Danny: мое первоначальное предложение не держит ключи в порядке. Если вам нужно отсортировать ключи, попробуйте:

>>> from collections import OrderedDict

>>> OrderedDict( (x,1) for x in mylist ).keys()
[3, 2, 1, 4, 5]

который сохраняет элементы в порядке по первому вхождению элемента (не тщательно протестирован)

от http://www.peterbe.com/plog/uniqifiers-benchmark:

def f5(seq, idfun=None):  
    # order preserving
    if idfun is None:
        def idfun(x): return x
    seen = {}
    result = []
    for item in seq:
        marker = idfun(item)
        # in old Python versions:
        # if seen.has_key(marker)
        # but in new ones:
        if marker in seen: continue
        seen[marker] = 1
        result.append(item)
    return result

Если все элементы списка могут быть использованы в качестве ключей словаря (т. е. все они хэшируются), это часто происходит быстрее. Python Программирование FAQ

d = {}
for x in mylist:
    d[x] = 1
mylist = list(d.keys())

самый простой способ удалить дубликаты при сохранении порядка-использовать сборники.OrderedDict (Python 2.7+).

from collections import OrderedDict
d = OrderedDict()
for x in mylist:
    d[x] = True
print d.iterkeys()

характеристики наборов в Python таковы, что элементы данных в наборе неупорядоченные и дубликаты не допускаются. При попытке добавить элемент данных в набор, который уже содержит элемент данных, Python просто игнорирует его.

>>> l = ['a', 'a', 'bb', 'b', 'c', 'c', '10', '10', '8','8', 10, 10, 6, 10, 11.2, 11.2, 11, 11]
>>> distinct_l = set(l)
>>> print(distinct_l)
set(['a', '10', 'c', 'b', 6, 'bb', 10, 11, 11.2, '8'])

Comments

    Ничего не найдено.