:: (ทวิภาคคู่) ใน Python คืออะไรเมื่อลำดับการห้อย


263

ฉันรู้ว่าฉันสามารถใช้สิ่งที่ต้องการstring[3:4]รับสายอักขระย่อยใน Python แต่สิ่งที่ 3 หมายถึงsomesequence[::3]อะไร


ผู้ที่มาก่อน::อย่าง[5::]นี้หมายความว่าอย่างไร แล้วมันหมายความว่าอะไรโดย 5
Umar Asghar

1
[5 ::] จะหมายถึงเริ่มต้นด้วยองค์ประกอบแรกไม่มีอะไรสำหรับองค์ประกอบที่สองและเลือกองค์ประกอบถัดไป
Gagan

คำตอบ:


243

มันหมายถึง 'ไม่มีอะไรสำหรับการโต้แย้งครั้งแรกไม่มีอะไรสำหรับที่สองและกระโดดสาม' จะได้รับทุก ๆ สามรายการของลำดับที่หั่นบาง ๆ Extended Sliceเป็นสิ่งที่คุณต้องการ ใหม่ใน Python 2.3


99
นอกจากนี้ยังสามารถใช้เพื่อย้อนกลับรายการโดยใช้ [:: - 1]
thavan

22
ก็จะส่งกลับทุกรายการกับตำแหน่งที่เป็นที่หลาย 3 ตั้งแต่ 3 * 0 = 0 จะส่งคืนไอเท็มในตำแหน่ง 0 เช่น: range(10)[::3]เอาต์พุต[0, 3, 6, 9]
Ricky Robinson

1
หมายความว่าใครมาก่อน::เหมือน [n ::] ดังนั้นมันหมายความว่าnอย่างไร
Umar Asghar

154

ที่อยู่ชิ้นของ Python สามารถเขียนเป็น [start: end: step] และสามารถเริ่มต้นหยุดหรือสิ้นสุดได้ a[::3]คือทุกองค์ประกอบที่สามของลำดับ


85

seq[::n]เป็นลำดับของแต่ละnรายการ -th ในลำดับทั้งหมด

ตัวอย่าง:

>>> range(10)[::2]
[0, 2, 4, 6, 8]

ไวยากรณ์คือ:

seq[start:end:step]

ดังนั้นคุณสามารถทำได้:

>>> range(100)[5:18:2]
[5, 7, 9, 11, 13, 15, 17]

4
ใน Python 3 ช่วงตัวอย่างของคุณ (N) [:: ขั้นตอน] จะสร้างวัตถุช่วงไม่ใช่รายการ ในการดูสิ่งที่เกิดขึ้นจริงคุณต้องบีบบังคับช่วงของรายการ np.array ฯลฯ
PikalaxALT

57

คำอธิบาย

s[i:j:k]คือตามเอกสาร "ส่วนของ s จาก i ถึง j ด้วยขั้นตอน k" เมื่อใดiและjไม่อยู่ลำดับทั้งหมดจะถูกสันนิษฐานและs[::k]หมายถึง "ทุกรายการ k-th"

ตัวอย่าง

อันดับแรกให้เริ่มต้นรายการ:

>>> s = range(20)
>>> s
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

ลองมาทุก 3 รายการจากs:

>>> s[::3]
[0, 3, 6, 9, 12, 15, 18]

ลองมาทุก 3 รายการจากs[2:]:

>>> s[2:]
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> s[2::3]
[2, 5, 8, 11, 14, 17]

ลองมาทุก 3 รายการจากs[5:12]:

>>> s[5:12]
[5, 6, 7, 8, 9, 10, 11]
>>> s[5:12:3]
[5, 8, 11]

ลองมาทุก 3 รายการจากs[:10]:

>>> s[:10]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> s[:10:3]
[0, 3, 6, 9]

คำตอบที่น่าทึ่ง!
Jürgen K.

30

TL; DR

ตัวอย่างภาพนี้จะแสดงให้คุณเห็นถึงวิธีการเลือกองค์ประกอบอย่างประณีตใน NumPy Matrix (อาร์เรย์ 2 มิติ) ในแบบที่สนุกสนาน (ฉันสัญญา) ขั้นตอนที่ 2 ด้านล่างแสดงการใช้ "double colons" ที่เป็น::ปัญหา

(ข้อควรระวัง: นี่เป็นตัวอย่างเฉพาะของอาร์เรย์ NumPy โดยมีจุดประสงค์ในการอธิบายกรณีการใช้งานของ "double colons" ::สำหรับการกระโดดขององค์ประกอบในหลายแกนตัวอย่างนี้ไม่ครอบคลุมโครงสร้างข้อมูลไพ ธ อนดั้งเดิมเช่นList )

ตัวอย่างที่เป็นรูปธรรมหนึ่งข้อสำหรับควบคุมทั้งหมด ...

สมมติว่าเรามีเมทริกซ์ NumPy ที่มีลักษณะเช่นนี้:

In [1]: import numpy as np

In [2]: X = np.arange(100).reshape(10,10)

In [3]: X
Out[3]:
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
       [30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
       [40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
       [50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
       [60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
       [70, 71, 72, 73, 74, 75, 76, 77, 78, 79],
       [80, 81, 82, 83, 84, 85, 86, 87, 88, 89],
       [90, 91, 92, 93, 94, 95, 96, 97, 98, 99]])

พูดด้วยเหตุผลบางอย่างเจ้านายของคุณต้องการให้คุณเลือกองค์ประกอบต่อไปนี้:

ป้อนคำอธิบายรูปภาพที่นี่

"แต่ยังไง ???" ... อ่านต่อ! (เราสามารถทำได้ 2 วิธี)

ขั้นตอนที่ 1 - รับเซตย่อย

ระบุ "ดัชนีเริ่มต้น" และ "ดัชนีสิ้นสุด" ในทั้งทิศทางแถวแถวและคอลัมน์อัจฉริยะ

ป้อนคำอธิบายรูปภาพที่นี่

ในรหัส:

In [5]: X2 = X[2:9,3:8]

In [6]: X2
Out[6]:
array([[23, 24, 25, 26, 27],
       [33, 34, 35, 36, 37],
       [43, 44, 45, 46, 47],
       [53, 54, 55, 56, 57],
       [63, 64, 65, 66, 67],
       [73, 74, 75, 76, 77],
       [83, 84, 85, 86, 87]])

แจ้งให้ทราบล่วงหน้าตอนนี้เราเพิ่งได้รับส่วนย่อยของเราด้วยการใช้เทคนิคการทำดัชนีเริ่มต้นและสิ้นสุดอย่างง่าย ต่อไปจะทำอย่างไร "กระโดด" ... (อ่านต่อ!)

ขั้นตอนที่ 2 - เลือกองค์ประกอบ (พร้อมอาร์กิวเมนต์ "ข้ามขั้นตอน")

ตอนนี้เราสามารถระบุ "ขั้นตอนการกระโดด" ได้ทั้งในทิศทางแถวและคอลัมน์แบบฉลาด (เพื่อเลือกองค์ประกอบด้วยวิธี "กระโดด") ดังนี้:

ป้อนคำอธิบายรูปภาพที่นี่

ในรหัส (หมายเหตุโคลอนคู่):

In [7]: X3 = X2[::3, ::2]

In [8]: X3
Out[8]:
array([[23, 25, 27],
       [53, 55, 57],
       [83, 85, 87]])

เราเพิ่งเลือกองค์ประกอบทั้งหมดตามต้องการ! :)

 รวมขั้นตอนที่ 1 (เริ่มต้นและสิ้นสุด) และขั้นตอนที่ 2 ("กระโดด")

ตอนนี้เรารู้แนวคิดแล้วเราสามารถรวมขั้นตอนที่ 1 และขั้นตอนที่ 2 เข้าด้วยกันเป็นขั้นตอนเดียว - เพื่อความกะทัดรัด:

In [9]: X4 = X[2:9,3:8][::3,::2]

    In [10]: X4
    Out[10]:
    array([[23, 25, 27],
           [53, 55, 57],
           [83, 85, 87]])

ทำ!


ถ้าฉันต้องการตั้งค่ารายการที่ทำเครื่องหมายแต่ละรายการเป็น 0 ในวัตถุต้นฉบับ จะดำเนินการอย่างไร
user1211030

1
ทำX[2:9,3:8][::3,::2] = 0 (เพื่อแทนที่รายการที่ทำเครื่องหมายเป็น 0) ถ้าคุณพิมพ์อีกครั้งคุณจะเห็นทุกรายการที่ทำเครื่องหมายไว้ผู้ที่มีการตั้งค่าในขณะนี้เพื่อX 0
Atlas7

15

เมื่อแบ่งส่วนใน Python พารามิเตอร์ที่สามคือขั้นตอน ตามที่คนอื่นพูดถึงดูExtended Sliceสำหรับภาพรวมที่ดี

ด้วยความรู้นี้[::3]หมายความว่าคุณไม่ได้ระบุดัชนีเริ่มต้นหรือสิ้นสุดสำหรับชิ้นของคุณ เนื่องจากคุณได้ระบุขั้นตอน3สิ่งนี้จะใช้เวลาทุกรายการที่สามของการsomethingเริ่มต้นที่ดัชนีแรก ตัวอย่างเช่น:

>>> '123123123'[::3]
'111'

7

นอกจากนี้คุณยังสามารถใช้สัญลักษณ์นี้ในคลาสที่คุณกำหนดเองเพื่อทำสิ่งที่คุณต้องการ

class C(object):
    def __getitem__(self, k):
        return k

# Single argument is passed directly.
assert C()[0] == 0

# Multiple indices generate a tuple.
assert C()[0, 1] == (0, 1)

# Slice notation generates a slice object.
assert C()[1:2:3] == slice(1, 2, 3)

# If you omit any part of the slice notation, it becomes None.
assert C()[:] == slice(None, None, None)
assert C()[::] == slice(None, None, None)
assert C()[1::] == slice(1, None, None)
assert C()[:2:] == slice(None, 2, None)
assert C()[::3] == slice(None, None, 3)

# Tuple with a slice object:
assert C()[:, 1] == (slice(None, None, None), 1)

# Ellipsis class object.
assert C()[...] == Ellipsis

จากนั้นเราสามารถเปิดวัตถุชิ้นเป็น:

s = slice(1, 2, 3)
assert s.start == 1
assert s.stop == 2
assert s.step == 3

สิ่งนี้ถูกใช้อย่างโดดเด่นใน Numpy เพื่อแบ่งอาร์เรย์หลายมิติในทิศทางใด ๆ

แน่นอน API ที่มีเหตุผลใด ๆ ควรใช้::3กับความหมาย "ทุก 3" ตามปกติ

สิ่งที่เกี่ยวข้องEllipsisจะครอบคลุมเพิ่มเติมที่: วัตถุ Ellipsis ทำอะไร


6

พารามิเตอร์ที่สามคือขั้นตอน ดังนั้น [:: 3] จะส่งคืนองค์ประกอบที่ 3 ของรายการ / สตริง


4

Python ใช้ :: เพื่อแยก End, Start และค่า Step


1
นี่ไม่ได้ให้รายละเอียดเพียงพอที่จะเป็นประโยชน์
bstpierre

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