एक बूलियन सूची में सच्चे मूल्यों के सूचकांक प्राप्त करना


87

मेरे पास मेरे कोड का एक टुकड़ा है जहां मैं एक स्विचबोर्ड बनाने वाला हूं। मैं उन सभी स्विचों की सूची वापस करना चाहता हूं जो चालू हैं। यहां "ऑन" बराबर Trueऔर "ऑफ" बराबर होगा False। इसलिए अब मैं केवल सभी Trueमूल्यों और उनकी स्थिति की सूची वापस करना चाहता हूं । यह सब मेरे पास है, लेकिन यह केवल पहली घटना की स्थिति लौटाता है True(यह मेरे कोड का एक हिस्सा है):

self.states = [False, False, False, False, True, True, False, True, False, False, False, False, False, False, False, False]

def which_switch(self):
    x = [self.states.index(i) for i in self.states if i == True]

यह केवल "4" देता है

जवाबों:


115

उपयोग करें enumerate, list.indexपहले मैच का इंडेक्स मिला।

>>> t = [False, False, False, False, True, True, False, True, False, False, False, False, False, False, False, False]
>>> [i for i, x in enumerate(t) if x]
[4, 5, 7]

विशाल सूचियों के लिए, इसका उपयोग करना बेहतर होगा itertools.compress:

>>> from itertools import compress
>>> list(compress(xrange(len(t)), t))
[4, 5, 7]
>>> t = t*1000
>>> %timeit [i for i, x in enumerate(t) if x]
100 loops, best of 3: 2.55 ms per loop
>>> %timeit list(compress(xrange(len(t)), t))
1000 loops, best of 3: 696 µs per loop

आह, मैं देख रहा हूँ, मैंने कुछ ऐसे ही प्रश्न देखे जो मुझे बता रहे थे कि मुझे एन्यूमरेट का उपयोग करना है, लेकिन मुझे लगता है कि मैं इसका गलत उपयोग कर रहा था। मैं सूची के बराबर सेट कर रहा था x, फिर कर enumerate(x)रहा था , लेकिन मुझे लगता है कि मैं जो कर रहा था, वह सब 4 था? यह क्या हो रहा था? मदद के लिए धन्यवाद
चार्ल्स स्मिथ

इसके अलावा क्या हो रहा है जब आप i for i, xसूची में समझ लेते हैं ? मैं केवल i for iउदाहरण के लिए देखने के लिए उपयोग किया जाता हूं , या एक समान प्रारूप, किस का कार्य है x? धन्यवाद
चार्ल्स स्मिथ

1
@ enumerateअब लूप के दौरान एक टुपल्स (इंड, वैल्यू) देता है, अब हम टपल के आइटम को दो वेरिएबल्स का उपयोग करके असाइन कर सकते हैं i, x = (ind, value):। यह वास्तव में उस पाश में क्या हो रहा है।
अश्विनी चौधरी

ओह, मैं देख रहा हूं कि अब क्या हो रहा है। आपकी मदद के लिए बहुत बहुत धन्यवाद!
चार्ल्स स्मिथ

Python3 का उपयोग कर किसी के लिए, में itertools.compressसमाधान, बदलने xrangeके लिए range। ( अजगर 3 में xrangeनाम बदल दिया गया था range)
मेहमब

64

यदि आपके पास उपलब्ध है:

>>> import numpy as np
>>> states = [False, False, False, False, True, True, False, True, False, False, False, False, False, False, False, False]
>>> np.where(states)[0]
array([4, 5, 7])

8
ध्यान दें कि यह एक टपल देता है जिसके np.where(states)[0]लिए वास्तव में परिणामों का उपयोग करने की आवश्यकता होती है
रुफस

17

टी एल; DR : इसका उपयोग np.whereसबसे तेज़ विकल्प है। आपके विकल्प हैं np.where, itertools.compressऔर list comprehension

नीचे विस्तृत तुलना देखें, जहां यह np.whereदोनों itertools.compressऔर भी बेहतर प्रदर्शनlist comprehension किया जा सकता है ।

>>> from itertools import compress
>>> import numpy as np
>>> t = [False, False, False, False, True, True, False, True, False, False, False, False, False, False, False, False]`
>>> t = 1000*t
  • विधि 1: का उपयोग कर list comprehension
>>> %timeit [i for i, x in enumerate(t) if x]
457 µs ± 1.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
  • विधि 2: का उपयोग कर itertools.compress
>>> %timeit list(compress(range(len(t)), t))
210 µs ± 704 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)
  • विधि 3 (सबसे तेज़ विधि): उपयोग करना numpy.where
>>> %timeit np.where(t)
179 µs ± 593 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

2

आप इसके लिए फ़िल्टर का उपयोग कर सकते हैं:

filter(lambda x: self.states[x], range(len(self.states)))

rangeयहाँ अपनी सूची के तत्वों विश्लेषण करता है और हम केवल उन जहां चाहते हैं के बाद से self.statesकिया गया है True, हम इस स्थिति के आधार पर एक फिल्टर आवेदन कर रहे हैं।

पायथन के लिए> 3.0:

list(filter(lambda x: self.states[x], range(len(self.states))))


1

शब्दकोश समझने के तरीके का उपयोग करें,

x = {k:v for k,v in enumerate(states) if v == True}

इनपुट:

states = [False, False, False, False, True, True, False, True, False, False, False, False, False, False, False, False]

आउटपुट:

{4: True, 5: True, 7: True}

3
यह एक व्यापक-समझ की सूची नहीं समझ है।
अश्विनी चौधरी

1

तत्व-वार गुणा और सेट का उपयोग करना:

>>> states = [False, False, False, False, True, True, False, True, False, False, False, False, False, False, False, False]
>>> set(multiply(states,range(1,len(states)+1))-1).difference({-1})

आउटपुट: {4, 5, 7}


1

बस यह करें:

def which_index(self):
    return [
        i for i in range(len(self.states))
        if self.states[i] == True
    ]

आपके योगदान के लिए धन्यवाद और StackOverflow में आपका स्वागत है। हालाँकि, कृपया अपने स्वरूपण को बेहतर बनाने के लिए संपादन सहायता पढ़ें , और अपने कोड में कुछ स्पष्टीकरण भी जोड़ें। धन्यवाद!
विल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.