วิธีรับไอเท็มสุดท้ายของรายการใน Python


288

ฉันต้องการหมายเลข 9 รายการสุดท้ายและฉันแน่ใจว่ามีวิธีการแบ่งส่วน แต่ฉันไม่สามารถรับได้ ฉันได้ 9 ข้อนี้มาก่อน:

num_list[0:9]

คำตอบ:


519

คุณสามารถใช้จำนวนเต็มลบกับตัวดำเนินการแบ่งสำหรับสิ่งนั้น นี่คือตัวอย่างการใช้ตัวแปล python CLI:

>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
>>> a
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
>>> a[-9:]
[4, 5, 6, 7, 8, 9, 10, 11, 12]

เส้นสำคัญคือ a[-9:]


11
โปรดทราบว่าเป็น-0 0ดังนั้นa[-0:]ผลตอบแทนทั้งไม่องค์ประกอบสุดท้ายเป็นศูนย์a สำหรับการดูแลศูนย์คุณสามารถใช้[] a[-n:] if n > 0 else []
nekketsuuu

93

ดัชนีเชิงลบจะนับจากจุดสิ้นสุดของรายการดังนั้น:

num_list[-9:]

53

หั่น

Python slicing เป็นการดำเนินการที่รวดเร็วอย่างเหลือเชื่อและเป็นวิธีที่สะดวกในการเข้าถึงข้อมูลของคุณอย่างรวดเร็ว

สัญกรณ์ Slice เพื่อรับองค์ประกอบเก้าชิ้นล่าสุดจากรายการ (หรือลำดับอื่น ๆ ที่สนับสนุนมันเช่นเดียวกับสตริง) จะมีลักษณะดังนี้:

num_list[-9:]

เมื่อฉันเห็นสิ่งนี้ฉันอ่านส่วนในวงเล็บเป็น "9 ตั้งแต่ต้นจนจบ" (ที่จริงแล้วฉันย่อว่าจิตใจเป็น "-9, on")

คำอธิบาย:

สัญกรณ์เต็มคือ

sequence[start:stop:step]

แต่เครื่องหมายโคลอนเป็นสิ่งที่บอก Python ว่าคุณให้แบ่งเป็นส่วน ๆ และไม่ใช่ดัชนีทั่วไป นั่นเป็นเหตุผลว่าทำไมการคัดลอกรายการใน Python 2 จึงเป็นไปได้

list_copy = sequence[:]

และล้างพวกเขาด้วย:

del my_list[:]

(รายการได้รับlist.copyและlist.clearใน Python 3)

ตั้งชื่อที่สื่อความหมายได้!

คุณอาจพบว่ามีประโยชน์ในการแยกการขึ้นรูปชิ้นส่วนจากการส่งผ่านไปยังlist.__getitem__วิธีการ ( นั่นคือสิ่งที่วงเล็บเหลี่ยมทำ ) แม้ว่าคุณจะไม่ใหม่ แต่ก็ทำให้โค้ดของคุณอ่านง่ายขึ้นเพื่อให้ผู้อื่นที่อาจต้องอ่านรหัสของคุณสามารถเข้าใจสิ่งที่คุณกำลังทำอยู่ได้ง่ายขึ้น

อย่างไรก็ตามคุณไม่สามารถกำหนดจำนวนเต็มที่คั่นด้วยโคลอนให้กับตัวแปรได้ คุณต้องใช้วัตถุชิ้น:

last_nine_slice = slice(-9, None)

อาร์กิวเมนต์ที่สองNoneเป็นสิ่งจำเป็นเพื่อให้อาร์กิวเมนต์แรกจะถูกแปลเป็นstartอาร์กิวเมนต์มิฉะนั้นก็จะเป็นstopข้อโต้แย้ง

จากนั้นคุณสามารถส่งวัตถุชิ้นไปยังลำดับของคุณ:

>>> list(range(100))[last_nine_slice]
[91, 92, 93, 94, 95, 96, 97, 98, 99]

islice

isliceจากโมดูล itertools เป็นอีกวิธีหนึ่งในการทำสิ่งนี้ isliceไม่ได้ใช้อาร์กิวเมนต์เชิงลบดังนั้นการทำซ้ำได้ของคุณมี__reversed__วิธีพิเศษ - รายการใดมี - ดังนั้นคุณต้องผ่านรายการของคุณ (หรือ iterable ด้วย__reversed__) ไปreversedก่อน

>>> from itertools import islice
>>> islice(reversed(range(100)), 0, 9)
<itertools.islice object at 0xffeb87fc>

islice อนุญาตให้ประเมินผล data pipe อย่างขี้เกียจดังนั้นเพื่อให้ข้อมูลเป็นจริงส่งผ่านไปยัง constructor (เช่นlist):

>>> list(islice(reversed(range(100)), 0, 9))
[99, 98, 97, 96, 95, 94, 93, 92, 91]

ตัวย่อทางจิตของคุณมีประโยชน์มาก
Swanky Coder

40

9 องค์ประกอบสุดท้ายสามารถอ่านได้จากซ้ายไปขวาโดยใช้ numlist [-9:] หรือจากขวาไปซ้ายโดยใช้ numlist [: - 10: -1] ตามที่คุณต้องการ

>>> a=range(17)
>>> print a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
>>> print a[-9:]
[8, 9, 10, 11, 12, 13, 14, 15, 16]
>>> print a[:-10:-1]
[16, 15, 14, 13, 12, 11, 10, 9, 8]

6

ต่อไปนี้เป็นตัวเลือกสำหรับรับรายการ "หาง" ของ iterable:

ป.ร. ให้ไว้

n = 9
iterable = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

ผลลัพธ์ที่ต้องการ

[2, 3, 4, 5, 6, 7, 8, 9, 10]

รหัส

เราได้ผลลัพธ์หลังโดยใช้ตัวเลือกต่อไปนี้:

from collections import deque
import itertools

import more_itertools


# A: Slicing
iterable[-n:]


# B: Implement an itertools recipe
def tail(n, iterable):
    """Return an iterator over the last *n* items of *iterable*.

        >>> t = tail(3, 'ABCDEFG')
        >>> list(t)
        ['E', 'F', 'G']

    """
    return iter(deque(iterable, maxlen=n))
list(tail(n, iterable))


# C: Use an implemented recipe, via more_itertools
list(more_itertools.tail(n, iterable))


# D: islice, via itertools
list(itertools.islice(iterable, len(iterable)-n, None))


# E: Negative islice, via more_itertools
list(more_itertools.islice_extended(iterable, -n, None))

รายละเอียด

  • A. การแบ่งส่วนของ Python แบบดั้งเดิมนั้นมีอยู่ในภาษา ตัวเลือกนี้ทำงานร่วมกับลำดับเช่นสตริงรายการและสิ่งอันดับ แต่ชนิดของหั่นนี้ไม่ทำงานบนiteratorsiter(iterable)เช่น
  • บีสูตรitertools มันเป็นเรื่องทั่วไปที่จะทำงานใด ๆ iterable และแก้ไขปัญหา iterator ในการแก้ปัญหาที่ผ่านมา สูตรนี้จะต้องดำเนินการด้วยตนเองเนื่องจากไม่ได้รวมอยู่ในitertoolsโมดูลอย่างเป็นทางการ
  • C. มีการใช้สูตรหลายอย่างรวมถึงเครื่องมือหลัง (B) ในแพ็คเกจของบุคคลที่สาม การติดตั้งและนำเข้าไลบรารีเหล่านี้จะช่วยในการปรับใช้งานด้วยตนเอง หนึ่งในห้องสมุดเหล่านี้เรียกว่าmore_itertools(ติดตั้งผ่าน> pip install more-itertools); เห็นmore_itertools.tailไหม
  • D. สมาชิกของitertoolsห้องสมุด หมายเหตุไม่สนับสนุนหั่นเชิงลบ itertools.islice
  • E. มีการนำเครื่องมืออื่นมาใช้ในการmore_itertoolsสรุปitertools.isliceเพื่อรองรับการแบ่งส่วนเชิงลบ เห็นmore_itertools.islice_extendedไหม

ฉันจะใช้อันไหนดี

มันขึ้นอยู่กับ ในกรณีส่วนใหญ่การแบ่งส่วนข้อมูล (ตัวเลือก A ดังที่กล่าวไว้ในคำตอบอื่น ๆ ) เป็นตัวเลือกที่ง่ายที่สุดเนื่องจากสร้างขึ้นในภาษาและสนับสนุนประเภทการทำซ้ำส่วนใหญ่ สำหรับตัววนซ้ำทั่วไปเพิ่มเติมให้ใช้ตัวเลือกใด ๆ ที่เหลืออยู่ หมายเหตุตัวเลือก C และ E จำเป็นต้องติดตั้งไลบรารีบุคคลที่สามซึ่งผู้ใช้บางรายอาจพบว่ามีประโยชน์

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