मैं कैसे जांच सकता हूं कि एक सूची में एक और केवल एक सत्य मूल्य है?


83

अजगर में, मेरे पास एक सूची है जिसमें एक और केवल एक सत्य मूल्य होना चाहिए (वह है, bool(value) is True)। क्या इसके लिए जाँच करने का एक चतुर तरीका है? अभी, मैं पूरी सूची में पुनरावृति कर रहा हूं और मैन्युअल रूप से जांच कर रहा हूं:

def only1(l)
    true_found = False
    for v in l:
        if v and not true_found:
            true_found=True
        elif v and true_found:
             return False #"Too Many Trues"
    return true_found

यह अतुल्य लगता है और बहुत अजगर नहीं है। क्या ऐसा करने का कोई चतुर तरीका है?


2
मुझे लगता है कि आपका समाधान काफी ठीक है और यह पायथोनिक है!
— विम

1
आम लिस्प (= 1 (count-if #'identity list)):।
— कज़

7
sum(lst) == 1
— पाएल जीडी

स्पष्ट होने के लिए: क्या आप जांचना चाहते हैं कि केवल एक Trueया केवल एक सत्य मूल्य है?
— मार्सिन

जवाबों:


44

सबसे वर्बोज़ समाधान हमेशा सबसे असंगत समाधान नहीं होता है। इसलिए मैं सिर्फ एक मामूली संशोधन जोड़ता हूं (कुछ अनावश्यक बूलियन मूल्यांकन को बचाने के लिए):

def only1(l):
    true_found = False
    for v in l:
        if v:
            # a True was found!
            if true_found:
                # found too many True's
                return False 
            else:
                # found the first True
                true_found = True
    # found zero or one True value
    return true_found

यहाँ तुलना के लिए कुछ समय हैं:

# file: test.py
from itertools import ifilter, islice

def OP(l):
    true_found = False
    for v in l:
        if v and not true_found:
            true_found=True
        elif v and true_found:
             return False #"Too Many Trues"
    return true_found

def DavidRobinson(l):
    return l.count(True) == 1

def FJ(l):
    return len(list(islice(ifilter(None, l), 2))) == 1

def JonClements(iterable):
    i = iter(iterable)
    return any(i) and not any(i)

def moooeeeep(l):
    true_found = False
    for v in l:
        if v:
            if true_found:
                # found too many True's
                return False 
            else:
                # found the first True
                true_found = True
    # found zero or one True value
    return true_found

मेरा आउटपुट:

$ python -mtimeit -s 'import test; l=[True]*100000' 'test.OP(l)' 
1000000 loops, best of 3: 0.523 usec per loop
$ python -mtimeit -s 'import test; l=[True]*100000' 'test.DavidRobinson(l)' 
1000 loops, best of 3: 516 usec per loop
$ python -mtimeit -s 'import test; l=[True]*100000' 'test.FJ(l)' 
100000 loops, best of 3: 2.31 usec per loop
$ python -mtimeit -s 'import test; l=[True]*100000' 'test.JonClements(l)' 
1000000 loops, best of 3: 0.446 usec per loop
$ python -mtimeit -s 'import test; l=[True]*100000' 'test.moooeeeep(l)' 
1000000 loops, best of 3: 0.449 usec per loop

जैसा कि देखा जा सकता है, ओपी समाधान यहां तैनात अधिकांश अन्य समाधानों की तुलना में काफी बेहतर है। जैसा कि अपेक्षित था, शॉर्ट सर्किट व्यवहार वाले सबसे अच्छे हैं, विशेष रूप से जॉन क्लेमेंट्स द्वारा पोस्ट किए गए समाधान। कम से कम Trueएक लंबी सूची में दो शुरुआती मूल्यों के मामले के लिए।

यहाँ Trueबिल्कुल भी कोई मूल्य नहीं है :

$ python -mtimeit -s 'import test; l=[False]*100000' 'test.OP(l)' 
100 loops, best of 3: 4.26 msec per loop
$ python -mtimeit -s 'import test; l=[False]*100000' 'test.DavidRobinson(l)' 
100 loops, best of 3: 2.09 msec per loop
$ python -mtimeit -s 'import test; l=[False]*100000' 'test.FJ(l)' 
1000 loops, best of 3: 725 usec per loop
$ python -mtimeit -s 'import test; l=[False]*100000' 'test.JonClements(l)' 
1000 loops, best of 3: 617 usec per loop
$ python -mtimeit -s 'import test; l=[False]*100000' 'test.moooeeeep(l)' 
100 loops, best of 3: 1.85 msec per loop

मैंने सांख्यिकीय महत्व की जांच नहीं की, लेकिन दिलचस्प बात यह है कि इस बार एफजे द्वारा सुझाए गए दृष्टिकोण और विशेष रूप से जो जॉन क्लेमेंट्स द्वारा एक बार फिर स्पष्ट रूप से बेहतर दिखाई देते हैं।


4
उम्म - जल्दी सही समय को देखते हुए - 0.446सबसे तेज नहीं है?
— जॉन क्लेमेंट्स

2
@JonClements यही कारण है कि मैंने सबसे अधिक लिखा , अब इसे स्पष्ट कर दिया। (अधिकांश पोस्ट किए गए, अधिकांश परीक्षण नहीं किए गए ...)
— मूओइप

1
मुझे संदेह है कि जॉनकलीमेंट बहुत तेज है क्योंकि ज्यादातर anyसी
— मैथ्यू स्काउटन में

1
+1 आपकी शुरुआती लाइन के लिए। साथ सभी उत्तरों sum.. वास्तव में ओ पी के सरल और सीधा कोड से भी बदतर हैं
— विम

2
@MarkAmery मैंने पठनीयता और लालित्य (एक छोटे से एक भर्ती) और प्रदर्शन मूल्यांकन पर एक खंड जोड़ा। जैसा कि चतुराई से पूछा गया प्रश्न दोनों पहलुओं पर विचार का विषय होना चाहिए, मुझे लगता है। जैसा कि मैंने इसे देखा है, मैंने इन दोनों प्रासंगिक पहलुओं को संबोधित करने के लिए एक उत्तर प्रदान किया है। यदि आपको लगता है कि यह उत्तर उपयोगी नहीं है, तो बेझिझक नीचे उतरें।
— मूओइप जूल

259

आयात की आवश्यकता नहीं है:

def single_true(iterable):
    i = iter(iterable)
    return any(i) and not any(i)

वैकल्पिक रूप से, शायद अधिक पठनीय संस्करण:

def single_true(iterable):
    iterator = iter(iterable)

    # consume from "i" until first true or it's exhausted
    has_true = any(iterator) 

    # carry on consuming until another true value / exhausted
    has_another_true = any(iterator) 

    # True if exactly one true found
    return has_true and not has_another_true

यह:

  • यह सुनिश्चित करने के लिए लगता है कि iकोई सही मूल्य है
  • यह सुनिश्चित करने के लिए कि कोई अन्य वास्तविक मूल्य नहीं है, उस बिंदु से इसे देखने योग्य बनाए रखता है

34
@MatthewScouten नहीं ... हम एक iterable यहां से लेने वाली कर रहे हैं ... कोड चलाने की कोशिश करें ...
— जॉन क्लेमेंट्स

12
@ MatthewScouten के उपभोग के अनुसार। anyडॉक्स के अनुसार जैसे ही एक गैर-गलत मान पाया जाता है, वैसे ही वापस आ जाता है। उसके बाद, हम फिर से एक सच्चे मूल्य की तलाश करते हैं, और यदि इसे असफल माना जाता है ... तो यह खाली सूचियों, सूचियों / अन्य अनुक्रमों, और किसी भी पुनरावृत्ति के लिए काम करेगा ...
— जॉन क्लेमेंट्स

12
@ मैथ्यूस्काउटेन साइड इफेक्ट्स सभी प्रमेयों को तोड़ते हैं! x and not x = Falseकेवल तभी सही है जब xसंदर्भात्मक रूप से पारदर्शी हो।
— बेन

14
@wim यह है नहीं के एक कार्यान्वयन विस्तार any()है समारोह के एक दस्तावेज विशेषता यह, और किसी भी लागू करने की गारंटी कार्यक्षमता कि अजगर कल्पना के अनुरूप -।
— गारेथ लेटी

17
जो कोई भी यह सोचता है कि यह एक पठनीय समाधान नहीं है, इस पर विचार करना चाहिए: यह संक्षिप्त है और केवल ज्ञात व्यवहारों और Pyon के सामान्य निर्माण पर निर्भर करता है। सिर्फ इसलिए कि एक noob इसे समझ नहीं पाएगा, यह पठनीय नहीं बनाता है। यह शिक्षण का एक उत्कृष्ट साधन भी है, जिसे जानना चाहिए क्योंकि यह उन लोगों में तत्काल जिज्ञासा पैदा करता है जो यह नहीं देखते हैं कि यह कैसे काम करता है।
— डैंसलमो

49

यह निर्भर करता है कि क्या आप केवल मूल्य की तलाश Trueकर रहे हैं या अन्य मूल्यों की तलाश कर रहे हैं जो Trueतार्किक रूप से मूल्यांकन करेंगे (जैसे 11या "hello")। यदि पूर्व:

def only1(l):
    return l.count(True) == 1

यदि उत्तरार्द्ध:

def only1(l):
    return sum(bool(e) for e in l) == 1

चूंकि यह एक नई सूची बनाने के लिए एक ही पुनरावृत्ति में गिनती और रूपांतरण दोनों को करेगा।


2
अजगर 3 में:list(map(bool, l)).count(True)
— प्रहार

यह केवल शाब्दिक सत्य को पाता है, अन्य सच्चे मूल्यों को नहीं (अर्थात: सकारात्मक चींटियों को खाली कंटेनर नहीं, आदि)
— मैथ्यू स्काउटन

6
बस ओपी को इंगित करने के लिए यह संभावना शॉर्ट सर्किट नहीं होगी जब एक से अधिक "ट्रू" मान पाया जाता है, इसलिए उनका कोड उन्हें कुछ परिस्थितियों में अधिक दक्षता दे सकता है।
— नोमिनसिम

2
दूसरा फ़ंक्शन के रूप में लिखा जा सकता है return sum(bool(e) for e in l) == 1। अंकगणित के संबंध में boolउपवर्ग intऔर सत्य / असत्य 1/0 के रूप में व्यवहार करते हैं।

1
मैं lएक चर नाम के रूप में उपयोग करने से बचूंगा (यह 1यहां बहुत पसंद है), और मैं फिर sum(bool(e) for e in l)से sum(1 for e in l if e)
— लिखूंगा

22

एक-लाइन का उत्तर जो शॉर्ट-सर्किटिंग व्यवहार को बनाए रखता है:

from itertools import ifilter, islice

def only1(l):
    return len(list(islice(ifilter(None, l), 2))) == 1

यह बहुत बड़े पुनरावृत्तियों के लिए यहां अन्य विकल्पों की तुलना में काफी तेज होगा, जिनमें दो या अधिक सच्चे मूल्य अपेक्षाकृत जल्दी हैं।

ifilter(None, itr)एक पुनरावृत्ति देता है जो केवल सत्य तत्व देगा ( xयदि bool(x)रिटर्न है तो सत्य है True)। islice(itr, 2)एक पुनरावृत्ति देता है जो केवल पहले दो तत्वों का उत्पादन करेगा itr। इसे एक सूची में परिवर्तित करके और जाँच कर लें कि लंबाई एक के बराबर है, हम यह सत्यापित कर सकते हैं कि हम दो पाए जाने के बाद किसी भी अतिरिक्त तत्वों की जाँच करने की आवश्यकता के बिना वास्तव में एक सत्य तत्व मौजूद है।

यहाँ कुछ समय तुलना कर रहे हैं:

  • सेटअप कोड:

    In [1]: from itertools import islice, ifilter
    
    In [2]: def fj(l): return len(list(islice(ifilter(None, l), 2))) == 1
    
    In [3]: def david(l): return sum(bool(e) for e in l) == 1
    
  • शॉर्ट-सर्किट व्यवहार का प्रदर्शन:

    In [4]: l = range(1000000)
    
    In [5]: %timeit fj(l)
    1000000 loops, best of 3: 1.77 us per loop
    
    In [6]: %timeit david(l)
    1 loops, best of 3: 194 ms per loop
    
  • बड़ी सूची जहां शॉर्ट-सर्कुलेटिंग नहीं होती है:

    In [7]: l = [0] * 1000000
    
    In [8]: %timeit fj(l)
    100 loops, best of 3: 10.2 ms per loop
    
    In [9]: %timeit david(l)
    1 loops, best of 3: 189 ms per loop
    
  • छोटी सूची:

    In [10]: l = [0]
    
    In [11]: %timeit fj(l)
    1000000 loops, best of 3: 1.77 us per loop
    
    In [12]: %timeit david(l)
    1000000 loops, best of 3: 990 ns per loop
    

इसलिए sum()दृष्टिकोण बहुत छोटी सूचियों के लिए तेज़ है, लेकिन इनपुट सूची बड़ी होने के बावजूद मेरा संस्करण तब भी तेज़ है जब शॉर्ट-सर्कुलेटिंग संभव नहीं है। जब एक बड़े इनपुट पर शॉर्ट-सर्कुलेटिंग संभव है, तो प्रदर्शन अंतर स्पष्ट है।


5
आउच। समझने के लिए अन्य विकल्पों के रूप में मुझे तीन बार लिया। यदि शॉर्ट-सर्किटिंग महत्वपूर्ण है, तो मैं ओपी कोड ले लूंगा क्योंकि यह अधिक स्पष्ट और मोटे तौर पर कुशल है।

1
स्टाइल के लिए वोट करें, और शॉर्ट सर्किट को बनाए रखें। लेकिन यह पढ़ना कठिन है।
— मैथ्यू स्काउटन

1
+1। ओपी के शॉर्ट-सर्कुलेटिंग के पूर्ण इरादे को पुन: पेश करने वाला एकमात्र।
— नोमिनसिम

1
+1 यदि आप timeitओपी समाधान के लिए एक उद्देश्य-प्रदर्शन-वार तुलना के लिए कुछ प्रयोग प्रदान करते हैं।
— मूइओपिप

@Moooeeeep Naively यदि आपके पास एक अनंत चलने योग्य है जिसमें दो Trueमूल्य हैं "जल्दी", तो यह खत्म हो जाएगा, बनाम अन्य उत्तर उनके पहियों को हमेशा के लिए गिनने की कोशिश करते हुए घूमते हैं।
— नोमिनसिम

15

मैं नेक्रोमैंटर बैज अर्जित करना चाहता था, इसलिए मैंने जॉन क्लेमेंट्स के उत्कृष्ट उत्तर को सामान्य किया, शॉर्ट-सर्कुलेटिंग लॉजिक के लाभों को संरक्षित किया और किसी भी और सभी के साथ तेजी से विधेय की जाँच की।

इस प्रकार यहाँ है:

एन (ट्रूज़) = एन

def n_trues(iterable, n=1):
    i = iter(iterable)
    return all(any(i) for j in range(n)) and not any(i)

एन (ट्रूज़) <= n:

def up_to_n_trues(iterable, n=1):
    i = iter(iterable)
    all(any(i) for j in range(n))
    return not any(i)

एन (ट्रूज़)> = एन:

def at_least_n_trues(iterable, n=1):
    i = iter(iterable)
    return all(any(i) for j in range(n))

m <= N (trues) <= n

def m_to_n_trues(iterable, m=1, n=1):
    i = iter(iterable)
    assert m <= n
    return at_least_n_trues(i, m) and up_to_n_trues(i, n - m)

11
>>> l = [0, 0, 1, 0, 0]
>>> has_one_true = len([ d for d in l if d ]) == 1
>>> has_one_true
True

4
इसे क्यों ठुकरा दिया गया? मुझे लगता है कि यह सबसे सरल और सबसे अधिक पठनीय है।
— डान्सल्मो

1
@dansalmo: यह निश्चित रूप से कठिन है, लेकिन मेरा सिद्धांत यह है कि कई n00b पायथन प्रोग्रामर - शायद विशेष रूप से जावा पृष्ठभूमि वाले लोग - लंबे वाक्य रचना के साथ अधिक सहज महसूस करते हैं। (ख़ुद, मैं 5-10 साल पहले थोड़ा बहुत हुआ करता था, लेकिन आज मैं इसे
— अनप्रोफेशनल

5

तुम कर सकते हो:

x = [bool(i) for i in x]
return x.count(True) == 1

या

x = map(bool, x)
return x.count(True) == 1

@ JoranBeasley की विधि पर निर्माण:

sum(map(bool, x)) == 1

5
if sum([bool(x) for x in list]) == 1

(मान लें कि आपके सभी मूल्य बुलिश हैं।)

यह शायद तेज होगा बस इसे संक्षेप में लिखें

sum(list) == 1   

हालाँकि यह आपकी सूची में डेटा प्रकारों के आधार पर कुछ समस्याएं पैदा कर सकता है।


1
कुछ पूंजीकरण और विराम चिह्न यहाँ अच्छा होगा।
— स्टीवन रंबलस्की


4

यह काम करने लगता है और किसी भी चलने योग्य को संभालने में सक्षम होना चाहिए, न कि केवल listएस। यह जब भी संभव हो, अधिकतम क्षमता के लिए शॉर्ट-सर्किट करता है। अजगर 2 और 3 दोनों में काम करता है।

def only1(iterable):
    for i, x in enumerate(iterable):  # check each item in iterable
        if x: break                   # truthy value found
    else:
        return False                  # no truthy value found
    for x in iterable[i+1:]:          # one was found, see if there are any more
        if x: return False            #   found another...
    return True                       # only a single truthy value found

testcases = [  # [[iterable, expected result], ... ]
    [[                          ], False],
    [[False, False, False, False], False],
    [[True,  False, False, False], True],
    [[False, True,  False, False], True],
    [[False, False, False, True],  True],
    [[True,  False, True,  False], False],
    [[True,  True,  True,  True],  False],
]

for i, testcase in enumerate(testcases):
    correct = only1(testcase[0]) == testcase[1]
    print('only1(testcase[{}]): {}{}'.format(i, only1(testcase[0]),
                                             '' if correct else
                                             ', error given '+str(testcase[0])))

आउटपुट:

only1(testcase[0]): False
only1(testcase[1]): False
only1(testcase[2]): True
only1(testcase[3]): True
only1(testcase[4]): True
only1(testcase[5]): False
only1(testcase[6]): False

मैं इस दृष्टिकोण की तरह, कैसे चारों ओर तर्क दोबारा काम के बारे में iter(x for x in my_list if x)और उसके बाद का उपयोग कर next, हो सकता है का उपयोग करने से अच्छे mapऔरlist.index
— विम

@wim: हालांकि मैं दृष्टिकोण आप सुझाव का उपयोग नहीं किया है, आपकी टिप्पणी मेरी मूल जवाब संशोधित करने के लिए मुझे प्रेरित किया और यह और भी वृद्धिशील प्रकृति में और से छुटकारा हो जाता बनाने mapऔर list.index।
— मार्टिउ

3

सबसे अधिक एन सच्चे मूल्यों के लिए @ जॉनकल्स का समाधान बढ़ाया गया :

# Extend any() to n true values
def _NTrue(i, n=1):
    for x in xrange(n):
        if any(i): # False for empty
            continue
        else:
            return False
    return True

def NTrue(iterable, n=1):
    i = iter(iterable)
    return any(i) and not _NTrue(i, n)

संपादित करें: बेहतर संस्करण

def test(iterable, n=1): 
    i = iter(iterable) 
    return sum(any(i) for x in xrange(n+1)) <= n 

EDIT2: शामिल कम से कम यह सच है की हूँ और सबसे n सच के पर

def test(iterable, n=1, m=1): 
    i = iter(iterable) 
    return  m <= sum(any(i) for x in xrange(n+1)) <= n

1
नहीं, मेरा मतलब है सबसे। यह सच है लौटाता है यदि अधिक से अधिक एन सच-मान मान मौजूद: 1000 की एक सूची में जैसे 3 trues मिलेगा iterable.count(True) = 3, NTrue(iterable, 1) = False, NTrue(iterable, 2) = False, NTrue(iterable, 3) = True, NTrue(iterable, 4) = True, ... यह मूल रूप से फैली हुई है and not any(i)हिस्से के लिएand not any(i) and not any(i) and not...
— Nisan.H

1
all(any(i) for i in xrange(n)) and not any(i)यहाँ काम नहीं करता है?
— एरिक

@Eric के लिए ही सच वापसी होगी कि वास्तव में एन सच है। इसने मुझे anyएस के ऊपर योग करने का विचार दिया , हालाँकि।
— निसं

आप बल्कि मतलब है any(i) and not all(any(i) for x in xrange(n))?
— मूइओपिप

@moooeeeep True and not all(<n booleans>)तार्किक रूप से समान नहीं है count(True) <= n? पहली असफलता की स्थिति में सबसे छोटे संभव सेट और ब्रेक का परीक्षण करना अभी भी विचार है।
— निसान।

2
def only1(l)
    sum(map(lambda x: 1 if x else 0, l)) == 1

स्पष्टीकरण: mapफ़ंक्शन एक सूची को दूसरी सूची में कर रहा है, कर रहा है True => 1और False => 0। अब हमारे पास True या False की जगह 0s और 1s की सूची है। अब हम बस इस सूची को जोड़ते हैं और यदि यह 1 है, तो केवल एक ट्रू वैल्यू था।


1

क्या यह आप देख रहे हैं?

sum(l) == 1

यह एक सूची के लिए विफल रहता है: [२], क्योंकि लेखक ने यह निर्दिष्ट नहीं किया है कि तत्वों को केवल सही और गलत होना चाहिए, या १३ और
— vtlinh

1

पूर्णता के लिए और लूप पुनरावृत्ति के लिए पायथन के नियंत्रण प्रवाह के उन्नत उपयोग को प्रदर्शित करने के लिए, कोई व्यक्ति स्वीकृत उत्तर में अतिरिक्त लेखांकन से बच सकता है, जिससे यह थोड़ा तेज़ हो सकता है:

def one_bool_true(iterable):
    it = iter(iterable)
    for i in it:
        if i:
            break
    else:            #no break, didn't find a true element
        return False
    for i in it:     # continue consuming iterator where left off
        if i: 
            return False
    return True      # didn't find a second true.

उपरोक्त सरल नियंत्रण प्रवाह, लूप्स के पायथन की परिष्कृत विशेषता का उपयोग करता है: द else। शब्दार्थ यह है कि यदि आप उस पुनरावृत्त पर पुनरावृत्ति को समाप्त करते हैं जिसे आप बिना उपयोग कर रहे हैं break, तो आप फिर elseब्लॉक में प्रवेश करते हैं ।

यहां स्वीकृत उत्तर है, जो थोड़ा अधिक लेखांकन का उपयोग करता है।

def only1(l):
    true_found = False
    for v in l:
        if v:
            # a True was found!
            if true_found:
                # found too many True's
                return False 
            else:
                # found the first True
                true_found = True
    # found zero or one True value
    return true_found

इन समय के लिए:

import timeit
>>> min(timeit.repeat(lambda: one_bool_true([0]*100 + [1, 1])))
13.992251592921093
>>> min(timeit.repeat(lambda: one_bool_true([1, 1] + [0]*100)))
2.208037032979064
>>> min(timeit.repeat(lambda: only1([0]*100 + [1, 1])))
14.213872335107908
>>> min(timeit.repeat(lambda: only1([1, 1] + [0]*100)))
2.2482982632641324
>>> 2.2482/2.2080
1.0182065217391305
>>> 14.2138/13.9922
1.0158373951201385

इसलिए हम देखते हैं कि स्वीकृत उत्तर में थोड़ा अधिक समय लगता है (एक प्रतिशत से थोड़ा अधिक)।

स्वाभाविक रूप से, anyC में लिखा गया बिल्ट-इन का उपयोग करना बहुत तेज़ है (कार्यान्वयन के लिए जॉन क्लेमेंट का उत्तर देखें - यह संक्षिप्त रूप है):

>>> min(timeit.repeat(lambda: single_true([0]*100 + [1, 1])))
2.7257133318785236
>>> min(timeit.repeat(lambda: single_true([1, 1] + [0]*100)))
2.012824866380015

0
import collections

def only_n(l, testval=True, n=1):
    counts = collections.Counter(l)
    return counts[testval] == n

रैखिक समय। अंतर्निहित काउंटर क्लास का उपयोग करता है, जो कि आपको काउंट्स की जांच करने के लिए उपयोग करना चाहिए।

अपने प्रश्न को फिर से पढ़ना, ऐसा लगता है कि आप वास्तव में यह जांचना चाहते हैं कि केवल एक सत्य मूल्य है, बजाय एक Trueमूल्य के। इसे इस्तेमाल करे:

import collections

def only_n(l, testval=True, coerce=bool, n=1):
    counts = collections.Counter((coerce(x) for x in l))
    return counts[testval] == n

जब आप बेहतर केस प्रदर्शन प्राप्त कर सकते हैं, तो कुछ भी नहीं सबसे खराब स्थिति प्रदर्शन होता है। यह भी छोटा और पढ़ने में आसान है।

यहाँ सर्वश्रेष्ठ-केस प्रदर्शन के लिए अनुकूलित एक संस्करण है:

import collections
import itertools

def only_n(l, testval=True, coerce=bool, n=1):
    counts = collections.Counter()
    def iterate_and_count():
        for x in itertools.imap(coerce,l):
            yield x
            if x == testval and counts[testval] > n:
               break
    counts.update(iterate_and_count())
    return counts[testval] == n

सबसे खराब स्थिति का प्रदर्शन उच्च k(जैसा कि O(kn+c)) होता है, लेकिन यह पूरी तरह से सामान्य है।

यहां प्रदर्शन के साथ प्रयोग करने के लिए एक विचारधारा है: http://ideone.com/ZRrv2m


0

यहां कुछ ऐसा है जो किसी भी सच्चाई के लिए काम करना चाहिए, हालांकि इसमें कोई शॉर्ट-सर्किट नहीं है। पारस्परिक रूप से अनन्य तर्कों को निषिद्ध करने के लिए एक साफ तरीके की तलाश करते हुए मैंने इसे पाया:

if sum(1 for item in somelist if item) != 1:
    raise ValueError("or whatever...")

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.