जाँच करना कि क्या किसी सूची के सभी तत्व अद्वितीय हैं


104

यह जाँचने का सबसे अच्छा तरीका (पारंपरिक तरीके से सबसे अच्छा) क्या है कि किसी सूची के सभी तत्व अद्वितीय हैं?

एक Counterका उपयोग कर मेरा वर्तमान दृष्टिकोण है:

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

क्या मैं बेहतर कर सकता हूं?

जवाबों:


164

सबसे कुशल नहीं, लेकिन सीधे आगे और संक्षिप्त:

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

संभवतः छोटी सूचियों के लिए ज्यादा फर्क नहीं पड़ेगा।


यही मैं भी करता हूं। संभवतः बड़ी सूचियों के लिए कुशल नहीं है।
टॉकरिन

जरूरी नहीं, कि सशर्त के शरीर को निष्पादित करेगा यदि सूची में दोहराए जाने वाले तत्व हैं (उदाहरण में "# कुछ")।
यान

2
काफी अच्छा, अच्छा समाधान। मैं मुश्किल से <500 तत्वों को संभाल रहा हूं, इसलिए मुझे जो चाहिए वह करना चाहिए।
user225312

4
लंबी सूची के साथ दक्षता के बारे में चिंतित लोगों के लिए, यह है लंबी सूची है कि वास्तव में अद्वितीय हैं (जहां सभी तत्वों की जाँच की जरूरत है) के लिए कुशल। प्रारंभिक निकास समाधान वास्तव में अद्वितीय सूचियों के लिए लंबे समय तक (मेरे परीक्षणों में लगभग 2x लंबे समय तक) लेते हैं। इसलिए ... यदि आप अपनी अधिकांश सूचियों के अद्वितीय होने की उम्मीद करते हैं, तो इस सरल सेट लंबाई जाँच समाधान का उपयोग करें। यदि आप उम्मीद करते हैं कि आपकी अधिकांश सूचियाँ अद्वितीय नहीं होंगी, तो जल्दी निकलने के उपाय का उपयोग करें। कौन सा उपयोग करना है यह आपके उपयोग के मामले पर निर्भर करता है।
रस

यह उत्तर अच्छा है। हालांकि, चलो यहां सावधान रहें: len(x) > len(set(x))यह सच है जब तत्व xअद्वितीय नहीं हैं। इस प्रश्न का शीर्षक ठीक इसके विपरीत पूछता है: "यह
देखना कि

96

यहाँ एक दो-लाइनर है जो जल्दी बाहर भी करेगा:

>>> 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

5
+1 साफ और पूरी सूची के माध्यम से पुनरावृत्ति नहीं करता है अगर जरूरत नहीं है।
कोस

@ paul-mcguire: क्या आप इस कोड स्निपेट को Apache 2.0-संगत लाइसेंस (जैसे, Apache 2, 2/3-लाइन BSD, MIT, X11, zlib) के तहत लाइसेंस देने के इच्छुक होंगे। मैं इसे अपाचे 2.0 परियोजना में उपयोग कर रहा हूं, और क्योंकि स्टैकऑवरफ्लो की लाइसेंसिंग शर्तें फ़ुबर हैं , मैं आपसे मूल लेखक के रूप में पूछ रहा हूं।
रयान परमान

मैंने एमआईटी लाइसेंस का उपयोग करके अन्य कोड डाल दिया है, ताकि इस स्निपेट के लिए मेरे लिए काम करें। कुछ भी विशेष मुझे करने की आवश्यकता है?
पॉलएमसीजी

21

एक प्रारंभिक-निकास समाधान हो सकता है

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))सबसे तेज़ तरीका होने की उम्मीद करूँगा ।


मैंने अन्य उत्तर को स्वीकार कर लिया क्योंकि मैं विशेष रूप से अनुकूलन की तलाश में नहीं था।
user225312 21

2
आप इसे निम्न पंक्ति में रखकर छोटा कर सकते हैं s = set()...return not any(s.add(x) if x not in s else True for x in g)
एंड्रयू क्लार्क

क्या आप बता सकते हैं कि len(x) != len(set(x))यदि आप जल्दी बाहर निकलना आम नहीं है तो आप इससे अधिक तेज़ होने की उम्मीद क्यों करेंगे ? दोनों संचालन O (len (x)) नहीं हैं ? (जहां xमूल सूची है)
क्रिस रेडफोर्ड

ओह, मैं देखता हूं: आपकी विधि O (len (x)) नहीं है क्योंकि आप जांच करते हैंif x in s के अंदर ओ (लेन (x)) के लिए पाश।
क्रिस रेडफोर्ड

15

गति के लिए:

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

12

एक सेट में सभी प्रविष्टियों को जोड़ने और इसकी लंबाई की जांच करने के बारे में कैसे?

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

1
यान, आउच के बाद एक सेकंड का उत्तर दिया। छोटा एवं सुन्दर। किसी भी कारण से इस समाधान का उपयोग न करें?
जस्सोनलहार्ड 21

सभी अनुक्रम (जनरेटर विशेष रूप से) समर्थन नहीं करते हैं len()
पॉलएमसीजी

9

एक के लिए वैकल्पिक set, आप एक का उपयोग कर सकते हैं dict

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

9
मैं एक सेट पर एक तानाशाह का उपयोग करने के लिए बिल्कुल कोई फायदा नहीं देखता। बेवजह की बातों में उलझा हुआ लगता है।
मेटासोयर्स

3

एक और दृष्टिकोण पूरी तरह से, क्रमबद्ध और समूह का उपयोग करते हुए:

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

इसके लिए एक प्रकार की आवश्यकता होती है, लेकिन पहले दोहराया मूल्य पर बाहर निकलता है।


हैशिंग छँटाई की तुलना में तेज़ है
IceArdor

उसी समाधान का उपयोग करने के लिए यहां आया था groupbyऔर इस उत्तर को पाया। मुझे यह सबसे सुरुचिपूर्ण लगता है, क्योंकि यह एक एकल अभिव्यक्ति है और किसी भी अतिरिक्त चर या लूप-स्टेटमेंट की आवश्यकता के बिना अंतर्निहित टूल के साथ काम करता है।
लार्स ब्लमबर्ग

1
यदि आपकी सूची में मनमानी वस्तुएं हैं जो क्रमबद्ध नहीं हैं, तो आप id()उन्हें क्रमबद्ध करने के लिए फ़ंक्शन का उपयोग कर सकते हैं क्योंकि यह groupby()काम करने के लिए एक शर्त है :groupby(sorted(seq), key=id)
लार्स ब्लमबर्ग

3

यहाँ मज़े के लिए एक पुनरावर्ती 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

2

यहाँ एक पुनरावर्ती जल्दी निकलने का कार्य है:

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)    

यह एक कार्यात्मक शैली दृष्टिकोण रखते हुए अजीब (धीमी) रूपांतरणों का उपयोग किए बिना मेरे लिए पर्याप्त तेज़ है।


1
H in Tएक रैखिक खोज करता है, और T = L[1:]सूची के कटा हुआ भाग की प्रतिलिपि बनाता है, इसलिए यह अन्य समाधानों की तुलना में बहुत धीमा होगा जो बड़ी सूची में सुझाए गए हैं। यह ओ (एन ^ 2) मुझे लगता है, जबकि अन्य लोग ओ (एन) (सेट) या ओ (एन लॉग एन) (सॉर्टिंग बेस्ड सॉल्यूशंस) हैं।
ब्लेककनथ

1

इस बारे में कैसा है

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

0

आप यान के सिंटैक्स (len (x)> len (सेट (x))) का उपयोग कर सकते हैं, लेकिन सेट (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


यह f5 फ़ंक्शन सेट का उपयोग करने की तुलना में धीमा होगा जो गति के लिए बेहतर अनुकूलित है। महंगा "एपेंड" ऑपरेशन के कारण जब सूची वास्तव में बड़ी हो जाती है तो यह कोड टूटना शुरू हो जाता है। बड़ी सूचियों के साथ x = range(1000000) + range(1000000), रनिंग सेट (x) f5 (x) से तेज है। प्रश्न में आदेश की आवश्यकता नहीं है लेकिन यहां तक ​​कि सॉर्ट किया गया सेट (सेट (x)) अभी भी f5 (x) से अधिक तेज़ है
OkezieE

0

पांडस डेटाफ़्रेम में एक समान दृष्टिकोण का उपयोग करके यह जांचने के लिए कि क्या स्तंभ की सामग्री में अद्वितीय मान हैं:

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

मेरे लिए, यह एक लाख से अधिक पंक्तियों वाली डेटफ़्रेम में एक अंतर चर पर तात्कालिक है।


0

उपरोक्त सभी उत्तर अच्छे हैं, लेकिन मैं 30 सेकंड के अजगरall_unique से उदाहरण का उपयोग करना पसंद करता हूं

आपको set()डुप्लिकेट को निकालने के लिए दी गई सूची पर उपयोग करने की आवश्यकता है , सूची की लंबाई के साथ इसकी लंबाई की तुलना करें।

def all_unique(lst):
  return len(lst) == len(set(lst))

Trueयदि फ्लैट सूची में सभी मान हैं unique, तो यह वापस आ Falseजाता है

x = [1,2,3,4,5,6]
y = [1,2,2,3,4,5]
all_unique(x) # True
all_unique(y) # False

-3

भिखारियों के लिए:

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

मुझे यह उत्तर पसंद है, सिर्फ इसलिए कि यह काफी अच्छी तरह से दिखाता है कि सेट का उपयोग करते समय आपको किस कोड को लिखना नहीं पड़ता है। मैं इसे "शुरुआती लोगों के लिए" लेबल नहीं करूंगा, क्योंकि मेरा मानना ​​है कि शुरुआती लोगों को इसे सही तरीके से करना सीखना चाहिए; लेकिन मुझे कुछ अनुभवहीन डेवलपर्स मिले जो इस तरह के कोड को अन्य भाषाओं में लिखने के आदी थे।
cessor
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.