web-dev-qa-db-ja.com

リスト内のすべての要素が一意であるかどうかを確認する

リスト内のすべての要素が一意であるかどうかを確認する最良の方法(従来の方法と同様)は何ですか?

Counterを使用した現在のアプローチは次のとおりです。

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

もっと良くできますか?

86
user225312

最も効率的ではありませんが、単純明快です:

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

おそらく、短いリストでは大きな違いはありません。

142
yan

早期終了も行う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
87
PaulMcG

早期終了ソリューションは

_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))が最速の方法であることを期待します。

21
6502

速度のために:

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

セットにすべてのエントリを追加し、その長さをチェックするのはどうですか?

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

setの代わりに、dictを使用できます。

len({}.fromkeys(x)) == len(x)
9
Tugrul Ates

ソートおよびgroupbyを使用する完全に別のアプローチ:

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

並べ替えが必要ですが、最初の繰り返し値で終了します。

2
PaulMcG

再帰的な早期終了関数は次のとおりです。

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)    

機能的なスタイルのアプローチをしながら、奇妙な(遅い)変換を使用せずに十分に高速です。

2
mhourdakis

再帰的なO(N2)楽しみのためのバージョン:

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

これはどう

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

Pandasデータフレームで同様のアプローチを使用して、列の内容に一意の値が含まれているかどうかをテストします。

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

私にとって、これは100万行を超える日付フレームのint変数で瞬間的です。

1
user1718097

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

len(x)> len(f5(x))を実行します。これは高速であり、順序も維持されます。

そこからコードが取得されます: http://www.peterbe.com/plog/uniqifiers-benchmark

0
canisrufus