पायथन सूची में ट्रू बुलियन की संख्या की गिनती


152

मेरे पास बूलियंस की एक सूची है:

[True, True, False, False, False, True]

और मैं Trueसूची में संख्या की गणना करने का एक तरीका ढूंढ रहा हूं (इसलिए ऊपर के उदाहरण में, मैं चाहता हूं कि वापसी हो 3।) मुझे विशिष्ट तत्वों की घटनाओं की संख्या की तलाश के उदाहरण मिले हैं, लेकिन क्या कोई और अधिक है कुशल तरीका यह करने के बाद से मैं बूलियन के साथ काम कर रहा हूँ? मैं कुछ के बारे में सोच रहा हूँ allया any


जैसे यदि आपको याद है कि केवल असेंबलर का उपयोग करके हार्डवेयर में बिट की गिनती कैसे की गई थी।
व्लादिस्लाव्स डोवलगेक्स 21

जवाबों:


207

Trueके बराबर है 1

>>> sum([True, True, False, False, False, True])
3

23
यह मुहावरेदार नहीं है और मल के प्रकार के "दुरुपयोग" बनाता है।
Jan Segre

24
@ जीन सेग्रे, कोई जबरदस्ती नहीं है, बूल एक पूर्णांक प्रकार है।
पांडा -34

25
@ पांडा -34, मैंने जाँच की और issubclass(bool, int)वास्तव में पकड़ में है, इसलिए कोई जबरदस्ती नहीं है।
जन सेग्रे

153

listएक countविधि है:

>>> [True,True,False].count(True)
2

यह वास्तव में से अधिक कुशल है sum, साथ ही इरादे के बारे में अधिक स्पष्ट है, इसलिए उपयोग करने का कोई कारण नहीं है sum:

In [1]: import random

In [2]: x = [random.choice([True, False]) for i in range(100)]

In [3]: %timeit x.count(True)
970 ns ± 41.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [4]: %timeit sum(x)
1.72 µs ± 161 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

2
यदि 0 मान भी है
कोस्टानोस

10
sumयदि आप अन्य "सही" मानों को 1 या ट्रू के अलावा अन्य उत्तर का उपयोग नहीं कर सकते हैं। इसके अलावा, प्रश्न में कुछ भी Trueया लेकिन उल्लेख नहीं किया गया था False
मार्क टोनलन

43

यदि आप केवल निरंतर के साथ संबंध रखते हैं True, तो एक साधारण sumठीक है। हालांकि, ध्यान रखें कि पायथन में अन्य मूल्यों का भी मूल्यांकन होता है Trueboolबिलिन का उपयोग करने के लिए एक अधिक मजबूत समाधान होगा :

>>> l = [1, 2, True, False]
>>> sum(bool(x) for x in l)
3

अद्यतन: यहाँ एक और समान रूप से मजबूत समाधान है जिसके अधिक पारदर्शी होने का लाभ है:

>>> sum(1 for x in l if x)
3

पीएस पायथन ट्रिविया: बिना सच True हो सकता है 1. चेतावनी: काम पर यह कोशिश मत करो!

>>> True = 2
>>> if True: print('true')
... 
true
>>> l = [True, True, False, True]
>>> sum(l)
6
>>> sum(bool(x) for x in l)
3
>>> sum(1 for x in l if x)
3

बहुत अधिक बुराई:

True = False

ठीक है, मैं आपका उदाहरण देखता हूं, और मैं देखता हूं कि यह क्या कर रहा है। इसके एलओएल-नेस के अलावा, क्या वास्तव में एक अच्छा कारण है जो आपने यहां दिखाया है?
एसी

1
हाँ, शीर्ष भाग के लिए। जैसा कि मैंने संकेत दिया, एक "सच" (एक ifबयान में) के लिए पायथन परीक्षण सिर्फ परीक्षण के लिए अधिक जटिल है TrueDocs.python.org/py3k/library/stdtypes.html#truth देखें । True = 2सिर्फ सुदृढ़ करने के लिए है कि "सच" की अवधारणा को और अधिक जटिल है था, थोड़े अतिरिक्त कोड (यानी उपयोग करके bool()) आप समाधान को अधिक मजबूत और अधिक सामान्य बना सकते हैं।
नेड डिली

9
पायथन 3 में, Trueऔर Falseकीवर्ड हैं और आप उन्हें बदल नहीं सकते हैं।
thePiercingPrince


5

पूर्णता की खातिर ( sumआमतौर पर बेहतर है), मैं यह उल्लेख करना चाहता था कि हम filterसत्य मूल्यों को प्राप्त करने के लिए भी उपयोग कर सकते हैं । सामान्य स्थिति में, filterएक फ़ंक्शन को पहले तर्क के रूप में स्वीकार करता है, लेकिन यदि आप इसे पास करते हैं None, तो यह सभी "सत्य" मूल्यों के लिए फ़िल्टर करेगा। यह सुविधा कुछ आश्चर्यजनक है, लेकिन अच्छी तरह से प्रलेखित है और पायथन 2 और 3 दोनों में काम करती है।

संस्करणों के बीच का अंतर यह है कि अजगर 2 में filterएक सूची देता है, इसलिए हम इसका उपयोग कर सकते हैं len:

>>> bool_list = [True, True, False, False, False, True]
>>> filter(None, bool_list)
[True, True, True]
>>> len(filter(None, bool_list))
3

लेकिन पायथन 3 में, filterएक पुनरावृत्त को लौटाता है, इसलिए हम उपयोग नहीं कर सकते हैं len, और यदि हम sum(किसी भी कारण से) उपयोग करने से बचना चाहते हैं , तो हमें पुनरावृत्ति को एक सूची में परिवर्तित करने का सहारा लेना होगा (जो इसे बहुत कम बनाता है):

>>> bool_list = [True, True, False, False, False, True]
>>> filter(None, bool_list)
<builtins.filter at 0x7f64feba5710>
>>> list(filter(None, bool_list))
[True, True, True]
>>> len(list(filter(None, bool_list)))
3

4

इस प्रश्न पर सभी उत्तरों और टिप्पणियों को पढ़ने के बाद, मैंने एक छोटा सा प्रयोग करने की सोची।

मैंने 50,000 यादृच्छिक बूलियन उत्पन्न किए sumऔर countउन्हें और उन पर बुलाया ।

यहाँ मेरे परिणाम हैं:

>>> a = [bool(random.getrandbits(1)) for x in range(50000)]
>>> len(a)
50000
>>> a.count(False)
24884
>>> a.count(True)
25116
>>> def count_it(a):
...   curr = time.time()
...   counting = a.count(True)
...   print("Count it = " + str(time.time() - curr))
...   return counting
... 
>>> def sum_it(a):
...   curr = time.time()
...   counting = sum(a)
...   print("Sum it = " + str(time.time() - curr))
...   return counting
... 
>>> count_it(a)
Count it = 0.00121307373046875
25015
>>> sum_it(a)
Sum it = 0.004102230072021484
25015

बस सुनिश्चित करने के लिए, मैंने इसे कई बार दोहराया:

>>> count_it(a)
Count it = 0.0013530254364013672
25015
>>> count_it(a)
Count it = 0.0014507770538330078
25015
>>> count_it(a)
Count it = 0.0013344287872314453
25015
>>> sum_it(a)
Sum it = 0.003480195999145508
25015
>>> sum_it(a)
Sum it = 0.0035257339477539062
25015
>>> sum_it(a)
Sum it = 0.003350496292114258
25015
>>> sum_it(a)
Sum it = 0.003744363784790039
25015

और जैसा कि आप देख सकते हैं, countकी तुलना में 3 गुना तेज है sum। इसलिए मैं सुझाव दूंगा कि countजैसा मैंने किया था, वैसे ही उपयोग करें count_it

पायथन संस्करण: 3.6.7
सीपीयू कोर: 4
रैम आकार: 16 जीबी
ओएस: उबंटू 18.04.1 एलटीएस


3

यह boolपहले के माध्यम से चलाने के लिए सुरक्षित है । यह आसानी से किया जाता है:

>>> sum(map(bool,[True, True, False, False, False, True]))
3

फिर आप वह सब कुछ पकड़ लेंगे जो पायथन ने सही बाल्टी में सच या गलत माना है:

>>> allTrue=[True, not False, True+1,'0', ' ', 1, [0], {0:0}, set([0])]
>>> list(map(bool,allTrue))
[True, True, True, True, True, True, True, True, True]

यदि आप चाहें, तो आप एक समझ का उपयोग कर सकते हैं:

>>> allFalse=['',[],{},False,0,set(),(), not True, True-1]
>>> [bool(i) for i in allFalse]
[False, False, False, False, False, False, False, False, False]

1

मैं पसंद करता हूं len([b for b in boollist if b is True])(या जनरेटर-अभिव्यक्ति समतुल्य), क्योंकि यह काफी आत्म-व्याख्यात्मक है। इग्नासियो वाज़केज़-अब्राम्स द्वारा प्रस्तावित उत्तर की तुलना में कम 'जादुई'।

वैकल्पिक रूप से, आप ऐसा कर सकते हैं, जो अभी भी मानता है कि बूल इंट के लिए परिवर्तनीय है, लेकिन सच के मूल्य के बारे में कोई धारणा नहीं बनाता है: ntrue = sum(boollist) / int(True)


आपके समाधान में कम से कम दो समस्याएं हैं। एक, यह एक ही मजबूती के मुद्दे से ग्रस्त है; कि आप सिर्फ परीक्षण को बदलकर ठीक कर सकते हैं if b। लेकिन, इससे भी महत्वपूर्ण बात यह है कि आप एक ऐसी फेहरिस्त सूची का निर्माण कर रहे हैं जिसमें सभी मूल्यों को एक बार में याद रखने की आवश्यकता होती है और आप lenजनरेटर अभिव्यक्ति के साथ उपयोग नहीं कर सकते । ऐसी प्रथाओं से बचने के लिए बेहतर है ताकि समाधान को स्केल किया जा सके।
नेड डीली

@ नी देवी: if bबिल्कुल गलत है। यह केवल तभी सही होगा जब प्रश्न उन वस्तुओं के बारे में था जो वास्तविक ट्रू बूलियन के बजाय ट्रू के रूप में मूल्यांकन करते हैं। मैं हालांकि आपका दूसरा बिंदु लेता हूं। उस स्थिति में संस्करण है sum(1 if b is True else 0 for b in boollist)
kampu

जैसा कि मैंने कहीं और उल्लेख किया है, यह मेरे लिए इस प्रश्न से स्पष्ट नहीं है कि क्या ओपी वास्तव में केवल 1 के साथ टाइप बूल की वस्तुओं को गिनने का मतलब है या उन मूल्यों का बड़ा और आम तौर पर अधिक उपयोगी सेट है जो सच का मूल्यांकन करते हैं। यदि पूर्व, तो एक पहचान परीक्षण सही दृष्टिकोण है लेकिन यह सीमित भी है। पाइथन में टाइप बूल की वस्तुएं अजीब तरह से बतख हैं, वैसे भी भाषा के लिए अपेक्षाकृत हाल ही में इसके अतिरिक्त। किसी भी मामले में मैं सरल के लिए जाना होगा:sum(1 for b in boollist if b is True)
नेड डीली
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.