Ответ 1
Не самый эффективный, но прямой и лаконичный:
if len(x) > len(set(x)):
pass # do something
Вероятно, это не будет иметь большого значения для коротких списков.
Каков наилучший способ (лучше, как обычно) проверить, уникальны ли все элементы в списке?
Мой текущий подход с использованием Counter
:
>>> x = [1, 1, 1, 2, 3, 4, 5, 6, 2]
>>> counter = Counter(x)
>>> for values in counter.itervalues():
if values > 1:
# do something
Могу ли я сделать лучше?
Не самый эффективный, но прямой и лаконичный:
if len(x) > len(set(x)):
pass # do something
Вероятно, это не будет иметь большого значения для коротких списков.
Вот двухстрочный, который также сделает ранний выход:
>>> 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
Раннее решение выхода может быть
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))
будет самым быстрым методом.
для скорости:
import numpy as np
x = [1, 1, 1, 2, 3, 4, 5, 6, 2]
np.unique(x).size == len(x)
Как добавить все записи в набор и проверить его длину?
len(set(x)) == len(x)
Альтернативу set
, вы можете использовать dict
.
len({}.fromkeys(x)) == len(x)
Другой подход полностью, используя отсортированные и groupby:
from itertools import groupby
is_unique = lambda seq: all(sum(1 for _ in x[1])==1 for x in groupby(sorted(seq)))
Он требует сортировки, но выходит из первого повторного значения.
Вот рекурсивная функция раннего выхода:
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)
Это достаточно быстро для меня, не используя странные (медленные) преобразования, пока с функциональным подходом.
Вот рекурсивная версия 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
Как насчет этого
def is_unique(lst):
if not lst:
return True
else:
return Counter(lst).most_common(1)[0][1]==1
Используя аналогичный подход в фрейме Pandas, чтобы проверить, содержит ли содержимое столбца уникальные значения:
if tempDF['var1'].size == tempDF['var1'].unique().size:
print("Unique")
else:
print("Not unique")
Для меня это мгновенно в переменной int в дате кадра, содержащем более миллиона строк.
Вы можете использовать синтаксис 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
Для начинающих:
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