แยกองค์ประกอบของรายการที่ตำแหน่งคี่


102

ดังนั้นฉันต้องการสร้างรายการซึ่งเป็นรายการย่อยของรายการที่มีอยู่บางส่วน

ตัวอย่างเช่น,

L = [1, 2, 3, 4, 5, 6, 7]ฉันต้องการสร้างรายการย่อยliที่liมีองค์ประกอบทั้งหมดในLตำแหน่งคี่

ในขณะที่ฉันสามารถทำได้โดย

L = [1, 2, 3, 4, 5, 6, 7]
li = []
count = 0
for i in L:
    if count % 2 == 1:
        li.append(i)
    count += 1

แต่ฉันต้องการทราบว่ามีวิธีอื่นที่จะทำได้อย่างมีประสิทธิภาพและมีจำนวนขั้นตอนน้อยกว่านี้หรือไม่


@WaleedKhan: ทำไมเขาต้องเขียนความเข้าใจในคำถาม?
Tamara Wijsman

1
: @TomWijsman comprehensions รายการ ETA: ไม่สนใจว่า: ฉันตามล่าและค้นพบคำตอบของคุณซึ่งบ่งบอกว่าคุณล้อเล่น ใส่หน้ายิ้มครั้งหน้า!
David Robinson

2
@DavidRobinson: แต่คนอื่นบอกได้ไหมว่า OP อาจไม่ชัดเจนว่าเขาหมายถึงอะไรด้วยคำสองคำที่คลุมเครือ เพียงแค่แทงที่นี่และมีความคิดเห็นบางอย่างเพื่อให้ผู้คนเตรียมพร้อมและเขียนเนื้อหาที่ดีขึ้น และเพื่อหลีกเลี่ยงการออกจาก OP หรือผู้เยี่ยมชมโดยไม่รู้ตัว ... :)
Tamara Wijsman

คำตอบ:


236

วิธีการแก้

ใช่คุณสามารถ:

l = L[1::2]

และนี่คือทั้งหมด ผลลัพธ์จะมีองค์ประกอบที่วางไว้ในตำแหน่งต่อไปนี้ ( 0- ตามดังนั้นองค์ประกอบแรกจึงอยู่ที่ตำแหน่ง0วินาทีที่1ฯลฯ ):

1, 3, 5

ดังนั้นผลลัพธ์ (ตัวเลขจริง) จะเป็น:

2, 4, 6

คำอธิบาย

[1::2]ที่สิ้นสุดเป็นเพียงสัญกรณ์สำหรับรายชื่อหั่น โดยปกติจะอยู่ในรูปแบบต่อไปนี้:

some_list[start:stop:step]

หากเราละเว้นstartค่าเริ่มต้น ( 0) จะถูกใช้ ดังนั้นองค์ประกอบแรก (ที่ตำแหน่ง0เนื่องจากดัชนีเป็นฐาน0) จะถูกเลือก ในกรณีนี้องค์ประกอบที่สองจะถูกเลือก

เนื่องจากองค์ประกอบที่สองถูกละไว้ค่าเริ่มต้นจึงถูกใช้ (ส่วนท้ายของรายการ) ดังนั้นรายการจะถูกซ้ำจากองค์ประกอบที่สองไปยังจุดสิ้นสุด

นอกจากนี้เรายังมีให้อาร์กิวเมนต์ที่สาม ( step) 2ซึ่งเป็น ซึ่งหมายความว่าจะมีการเลือกองค์ประกอบหนึ่งรายการถัดไปจะถูกข้ามไปและอื่น ๆ ...

ดังนั้นเพื่อสรุปในกรณีนี้[1::2]หมายถึง:

  1. ใช้องค์ประกอบที่สอง (ซึ่งเป็นองค์ประกอบที่แปลกถ้าคุณตัดสินจากดัชนี)
  2. ข้ามองค์ประกอบหนึ่ง (เพราะเรามีstep=2ดังนั้นเราจึงข้ามองค์ประกอบหนึ่งซึ่งตรงกันข้ามกับstep=1ที่เป็นค่าเริ่มต้น)
  3. รับองค์ประกอบถัดไป
  4. ทำซ้ำขั้นตอนที่ 2. -3 จนกว่าจะถึงจุดสิ้นสุดของรายการ

แก้ไข : @PreetKukreti ให้ลิงค์สำหรับคำอธิบายอื่นเกี่ยวกับสัญกรณ์การแบ่งรายการของ Python ดูที่นี่: อธิบายสัญกรณ์ชิ้นส่วนของ Python

พิเศษ - แทนที่ตัวนับด้วย enumerate()

ในรหัสของคุณคุณสร้างและเพิ่มตัวนับอย่างชัดเจน ใน Python ไม่จำเป็นเนื่องจากคุณสามารถระบุผ่านการทำซ้ำได้โดยใช้enumerate():

for count, i in enumerate(L):
    if count % 2 == 1:
        l.append(i)

ข้างต้นมีจุดประสงค์เดียวกับรหัสที่คุณใช้:

count = 0
for i in L:
    if count % 2 == 1:
        l.append(i)
    count += 1

ข้อมูลเพิ่มเติมเกี่ยวกับการจำลองforลูปด้วยตัวนับใน Python: การเข้าถึงดัชนีใน Python 'for' loops


@TomWijsman ดูคำถามนี้เพื่อทำความเข้าใจไวยากรณ์การแบ่งส่วน python
Preet Kukreti

คำถามถามตำแหน่งคี่ สิ่งนี้ทำให้ได้ตำแหน่ง(0,2,4,6); เสียงเหมือน OP ต้องการดัชนีซึ่งจะถูกกำหนดโดย(1,3,5) [1,2,3,4,5,6,7][1::2]
Marcin

@ Marcin: ใช่ฉันออกมาพร้อมกับข้อสรุปเดียวกัน (ดูการแก้ไข) สิ่งนี้ออกมาหลังจากที่ฉันได้อ่านรหัสของ OP อย่างละเอียดแล้ว ปัญหานี้เกิดจากฐานที่แตกต่างกันสำหรับการจัดทำดัชนี (สำหรับฉันองค์ประกอบ " แปลก " หมายถึงองค์ประกอบแรกสำหรับ OP ดูเหมือนว่าเป็นอันดับสองดังนั้นจึงจัดทำดัชนีที่1)
Tadeck

1
@ TomWijsman: ฉันขอโทษฉันไม่ได้สังเกตว่าคุณมีอะไรเปลี่ยนแปลงไป อันที่จริงมีลิงค์ แต่นำไปสู่โปรเจ็กต์ Numarray ไม่ใช่การlistแบ่งส่วนของ Python มันแตกต่างกันเล็กน้อยโดยเฉพาะอย่างยิ่งเนื่องจากlistชิ้นส่วนของมันไม่ได้อ้างอิงถึงรายการต้นฉบับ (ใน Numarray คุณจำเป็นต้องเรียกอย่างชัดเจน.copy()เพื่อให้มีบางสิ่งที่ไม่อ้างอิงอาร์เรย์ดั้งเดิม) แต่เป็นเรื่องดีที่มีบางอย่างที่ดีกว่าสำหรับผู้อ่านบางคน คุณช่วยวางลิงก์นี้ในความคิดเห็นได้ไหมเพื่อที่ฉันจะได้โหวตเพิ่มและจะปรากฏใต้คำตอบ
Tadeck

@Tadeck "ดัชนีเลขคี่" โดยธรรมชาติหมายถึงดัชนีที่เป็นเลขคี่
Marcin

12

สำหรับตำแหน่งคี่คุณอาจต้องการ:

>>>> list_ = list(range(10))
>>>> print list_[1::2]
[1, 3, 5, 7, 9]
>>>>

5

ฉันชอบความเข้าใจในรายการเพราะไวยากรณ์ของคณิตศาสตร์ (Set) แล้วสิ่งนี้:

L = [1, 2, 3, 4, 5, 6, 7]
odd_numbers = [y for x,y in enumerate(L) if x%2 != 0]
even_numbers = [y for x,y in enumerate(L) if x%2 == 0]

โดยทั่วไปถ้าคุณระบุมากกว่ารายการคุณจะได้รับดัชนีและความคุ้มค่าx yสิ่งที่ฉันทำอยู่ที่นี่คือการใส่ค่าyลงในรายการผลลัพธ์ (คู่หรือคี่) และใช้ดัชนีxเพื่อดูว่าจุดนั้นเป็นเลขคี่ ( x%2 != 0) หรือไม่


1
ไม่ควรแจกแจง (L) แทนการแจกแจง (รายการ) หรือไม่?
ab123

0

คุณสามารถใช้ตัวดำเนินการ AND แบบบิต&ได้ ลองดูด้านล่าง:

x = [1, 2, 3, 4, 5, 6, 7]
y = [i for i in x if i&1]
>>> 
[1, 3, 5, 7]

ตัวดำเนินการ Bitwise AND ใช้กับ 1 และเหตุผลที่ใช้งานได้เนื่องจากเลขคี่เมื่อเขียนด้วยเลขฐานสองจะต้องมีหลักแรกเป็น 1 มาตรวจสอบกัน

23 = 1 * (2**4) + 0 * (2**3) + 1 * (2**2) + 1 * (2**1) + 1 * (2**0) = 10111
14 = 1 * (2**3) + 1 * (2**2) + 1 * (2**1) + 0 * (2**0) = 1110

และการดำเนินการกับ 1 จะส่งกลับเพียง 1 เท่านั้น (1 ในไบนารีจะมีเลขหลักสุดท้าย 1 ด้วย) หากค่าเป็นเลขคี่

ตรวจสอบหน้า Python Bitwise Operatorสำหรับข้อมูลเพิ่มเติม

PS: คุณสามารถใช้วิธีนี้ในเชิงกลยุทธ์ได้หากคุณต้องการเลือกคอลัมน์คี่และคู่ในดาต้าเฟรม สมมติว่าพิกัด x และ y ของจุดสำคัญบนใบหน้าจะได้รับเป็นคอลัมน์ x1, y1, x2 ฯลฯ ... ในการปรับพิกัด x และ y ให้เป็นปกติด้วยค่าความกว้างและความสูงของแต่ละภาพคุณสามารถทำได้

for i in range(df.shape[1]):
    if i&1:
        df.iloc[:, i] /= heights
    else:
        df.iloc[:, i] /= widths

สิ่งนี้ไม่เกี่ยวข้องกับคำถาม แต่สำหรับนักวิทยาศาสตร์ข้อมูลและวิศวกรวิสัยทัศน์คอมพิวเตอร์วิธีนี้อาจเป็นประโยชน์

ไชโย!


-1

list_ = รายการ (ช่วง (9)) พิมพ์ (list_ [1 :: 2])


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