Подтвердить что ты не робот

Проверка уникальности всех элементов в списке

Каков наилучший способ (лучше, как обычно) проверить, уникальны ли все элементы в списке?

Мой текущий подход с использованием Counter:

>>> x = [1, 1, 1, 2, 3, 4, 5, 6, 2]
>>> counter = Counter(x)
>>> for values in counter.itervalues():
        if values > 1: 
            # do something

Могу ли я сделать лучше?

4b9b3361

Ответ 1

Не самый эффективный, но прямой и лаконичный:

if len(x) > len(set(x)):
   pass # do something

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

Ответ 2

Вот двухстрочный, который также сделает ранний выход:

>>> def allUnique(x):
...     seen = set()
...     return not any(i in seen or seen.add(i) for i in x)
...
>>> allUnique("ABCDEF")
True
>>> allUnique("ABACDEF")
False

Если элементы x не хешируются, вам придётся прибегнуть к использованию списка для seen:

>>> def allUnique(x):
...     seen = list()
...     return not any(i in seen or seen.append(i) for i in x)
...
>>> allUnique([list("ABC"), list("DEF")])
True
>>> allUnique([list("ABC"), list("DEF"), list("ABC")])
False

Ответ 3

Раннее решение выхода может быть

def unique_values(g):
    s = set()
    for x in g:
        if x in s: return False
        s.add(x)
    return True

однако для небольших случаев или если ранний выход не является обычным явлением, я бы ожидал, что len(x) != len(set(x)) будет самым быстрым методом.

Ответ 4

для скорости:

import numpy as np
x = [1, 1, 1, 2, 3, 4, 5, 6, 2]
np.unique(x).size == len(x)

Ответ 5

Как добавить все записи в набор и проверить его длину?

len(set(x)) == len(x)

Ответ 6

Альтернативу set, вы можете использовать dict.

len({}.fromkeys(x)) == len(x)

Ответ 7

Другой подход полностью, используя отсортированные и groupby:

from itertools import groupby
is_unique = lambda seq: all(sum(1 for _ in x[1])==1 for x in groupby(sorted(seq)))

Он требует сортировки, но выходит из первого повторного значения.

Ответ 8

Вот рекурсивная функция раннего выхода:

def distinct(L):
    if len(L) == 2:
        return L[0] != L[1]
    H = L[0]
    T = L[1:]
    if (H in T):
            return False
    else:
            return distinct(T)    

Это достаточно быстро для меня, не используя странные (медленные) преобразования, пока с функциональным подходом.

Ответ 9

Вот рекурсивная версия O (N 2) для развлечения:

def is_unique(lst):
    if len(lst) > 1:
        return is_unique(s[1:]) and (s[0] not in s[1:])
    return True

Ответ 10

Как насчет этого

def is_unique(lst):
    if not lst:
        return True
    else:
        return Counter(lst).most_common(1)[0][1]==1

Ответ 11

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

if tempDF['var1'].size == tempDF['var1'].unique().size:
    print("Unique")
else:
    print("Not unique")

Для меня это мгновенно в переменной int в дате кадра, содержащем более миллиона строк.

Ответ 12

Вы можете использовать синтаксис Yan (len (x) > len (set (x))), но вместо set (x) определить функцию:

 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

и do len (x) > len (f5 (x)). Это будет быстро, а также сохраняется порядок.

Код берется из: http://www.peterbe.com/plog/uniqifiers-benchmark

Ответ 13

Для начинающих:

def AllDifferent(s):
    for i in range(len(s)):
        for i2 in range(len(s)):
            if i != i2:
                if s[i] == s[i2]:
                    return False
    return True