การรับดัชนีของค่า True ในรายการบูลีน


88

ฉันมีโค้ดส่วนหนึ่งที่ฉันควรจะสร้างสวิตช์บอร์ด ฉันต้องการส่งคืนรายการสวิตช์ทั้งหมดที่เปิดอยู่ ที่นี่ "กับ" จะเท่ากับ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"

คำตอบ:


118

การใช้งาน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? นั่นคือสิ่งที่เกิดขึ้น? ขอบคุณสำหรับความช่วยเหลือ
Amon

นอกจากนี้จะเกิดอะไรขึ้นเมื่อคุณi for i, xทำความเข้าใจในรายการ ฉันเคยเห็นi for iตัวอย่างหรือรูปแบบที่คล้ายกันเท่านั้นมีหน้าที่xอะไร ขอบคุณ
อมร

1
@Amon enumerateส่งกลับ tuples (IND ค่า) ในระหว่างห่วงตอนนี้เราสามารถกำหนดรายการ tuple i, x = (ind, value)เพื่อสองตัวแปรโดยใช้: นี่คือสิ่งที่เกิดขึ้นในลูปนั้น
Ashwini Chaudhary

ฉันเห็นสิ่งที่เกิดขึ้นตอนนี้ ขอบคุณมากสำหรับความช่วยเหลือ!
Amon

สำหรับทุกคนที่ใช้ Python3 ในitertools.compressการแก้ปัญหาเปลี่ยนไปxrange range( xrangeเปลี่ยนชื่อเป็นrangePython 3)
MehmedB

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

TL; DR : ใช้np.whereเนื่องจากเป็นตัวเลือกที่เร็วที่สุด ตัวเลือกของคุณnp.where, และitertools.compresslist comprehension

ดูการเปรียบเทียบรายละเอียดด้านล่างที่มันสามารถมองเห็นได้np.whereมีประสิทธิภาพเหนือกว่าทั้งในitertools.compresslist 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เราจะใช้ตัวกรองซึ่งเป็นไปตามเงื่อนไขนี้

สำหรับ Python> 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
มันเป็นความเข้าใจตามคำบอกไม่ใช่รายการความเข้าใจ
Ashwini Chaudhary

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 อย่างไรก็ตามโปรดอ่านความช่วยเหลือในการแก้ไขเพื่อปรับปรุงการจัดรูปแบบของคุณและเพิ่มคำอธิบายบางอย่างลงในโค้ดของคุณ ขอบคุณ!
Will
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.