วิธีการลบองค์ประกอบจากรายการโดยดัชนี


1505

ฉันจะลบองค์ประกอบออกจากรายการตามดัชนีใน Python ได้อย่างไร

ฉันพบlist.removeวิธีการแล้ว แต่บอกว่าฉันต้องการลบองค์ประกอบสุดท้ายฉันจะทำสิ่งนี้ได้อย่างไร ดูเหมือนว่าการลบเริ่มต้นจะค้นหารายการ แต่ฉันไม่ต้องการให้ทำการค้นหาใด ๆ


10
@smci: รายการ Python ใช้อาเรย์: หากต้องการลบรายการที่อยู่ตรงกลางคุณต้องย้ายรายการทั้งหมดทางด้านขวาเพื่อลบช่องว่างที่เป็นสาเหตุของO(n)การดำเนินการเวลา deque()ให้การดำเนินงานที่มีประสิทธิภาพทั้งสองด้าน แต่ไม่มีการแทรก / ค้นหา / ลบ O (1) ที่อยู่ตรงกลาง
jfs

@JFSebastian: การใช้ cPython ใช่ขอบคุณสำหรับการแก้ไขฉัน ข้อมูลจำเพาะภาษาอย่างเคร่งครัดไม่ได้ระบุวิธีการใช้งานรายการการนำไปใช้ทางเลือกสามารถเลือกใช้รายการที่ลิงก์ได้
smci

@smci: ไม่มีการใช้ Python ที่ใช้งานได้จริงจะใช้O(n)การเข้าถึงดัชนีa[i](เนื่องจากมีการเชื่อมโยงรายการ) หมายเหตุ: การใช้งานแบบอาเรย์ให้O(1)การเข้าถึงดัชนี
jfs

@JFSebastian: แน่นอน ฉันเพิ่งสังเกตว่าสเป็คภาษาไม่ได้กำหนดสิ่งนี้มันเป็นปัญหาการใช้งาน (ฉันรู้สึกประหลาดใจที่พบว่าไม่ได้)
smci

@smci หากคุณกำลังกำหนดเป้าหมายในวงกว้างฉันไม่แน่ใจว่าคุณจะหวังที่จะเพิ่มประสิทธิภาพอะไรได้บ้าง
Nick T

คำตอบ:


1740

ใช้delและระบุดัชนีขององค์ประกอบที่คุณต้องการลบ:

>>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> del a[-1]
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8]

รองรับชิ้น:

>>> del a[2:4]
>>> a
[0, 1, 4, 5, 6, 7, 8, 9]

นี่คือส่วนจากการกวดวิชา


53
ขอบคุณความแตกต่างระหว่างป๊อปกับเดลคืออะไร
Joan Venge

37
เดลมีการใช้งานมากเกินไป ตัวอย่างเช่น del a ลบรายการทั้งหมด
Brian R. Bondy

34
อีกตัวอย่างหนึ่งลบ [2: 4] ลบองค์ประกอบ 2 และ 3
Brian R. Bondy

307
pop () คืนองค์ประกอบที่คุณต้องการลบ เดลเพียงแค่ลบคือ

13
ฉันไม่เห็นหลักฐานของ "รายการที่ลิงก์" ที่นั่น ดูsvn.python.org/projects/python/trunk/Objects/listobject.cPyList_GetItem()ผลตอบแทนเป็นอย่างไร((PyListObject *)op) -> ob_item[i];- iองค์ประกอบที่สำคัญของอาร์เรย์
glglgl

649

คุณอาจต้องการpop:

a = ['a', 'b', 'c', 'd']
a.pop(1)

# now a is ['a', 'c', 'd']

โดยค่าเริ่มต้นpopไม่มีข้อโต้แย้งใด ๆ ลบรายการสุดท้าย:

a = ['a', 'b', 'c', 'd']
a.pop()

# now a is ['a', 'b', 'c']

105
อย่าลืมป๊อป (-1) ใช่มันเป็นค่าเริ่มต้น แต่ฉันชอบมันดังนั้นฉันจึงไม่จำเป็นต้องจำป๊อปเอนด์ใดที่จะใช้เป็นค่าเริ่มต้น
S.Lott

282
ฉันไม่เห็นด้วย. หากคุณรู้ว่านิรุกติศาสตร์โปรแกรมเมอร์ "ป๊อป" (เป็นการดำเนินการที่ลบและส่งกลับด้านบนของโครงสร้างข้อมูล 'สแต็ค') แล้วpop()ตัวมันเองจะเห็นได้ชัดมากในขณะที่pop(-1)อาจทำให้สับสนเพราะซ้ำซ้อน
coredumperror

a.pop (-1) เพื่อลบอันสุดท้ายใช่ไหม
zx1986

14
@ zx1986 a popในภาษาการเขียนโปรแกรมส่วนใหญ่มักจะลบรายการสุดท้ายเช่นเดียวกับใน Python ดังนั้นไม่ว่าคุณจะระบุ -1 หรือไม่มีอะไรเหมือนกัน
ปาสกาล

30
โดยวิธีการpop()ส่งกลับองค์ประกอบอะไรก็ลบ
Bob Stein

136

เหมือนคนอื่น ๆ ที่กล่าวถึงป๊อปและเดมีวิธีที่มีประสิทธิภาพในการลบรายการของดัชนีได้รับ แต่เพื่อประโยชน์ในการสำเร็จ (เนื่องจากสามารถทำสิ่งเดียวกันได้หลายวิธีใน Python):

การใช้สไลซ์ (สิ่งนี้ไม่ได้แทนที่การลบไอเท็มจากรายการดั้งเดิม):

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

>>> a = [1, 2, 3, 4, 5, 6]
>>> index = 3 # Only positive index

>>> a = a[:index] + a[index+1 :]
# a is now [1, 2, 3, 5, 6]

หมายเหตุ:โปรดทราบว่าวิธีการนี้ไม่ได้ปรับเปลี่ยนรายการในสถานที่เช่นและpop delมันทำสำเนาสองรายการ (หนึ่งจากจุดเริ่มต้นจนถึงดัชนี แต่ไม่มี ( a[:index]) และหนึ่งหลังดัชนีจนถึงองค์ประกอบสุดท้าย ( a[index+1:]) และสร้างวัตถุรายการใหม่โดยการเพิ่มทั้งสองอย่าง สิ่งนี้ถูกกำหนดใหม่ให้กับตัวแปรรายการ ( a) รายการวัตถุเก่าจึงถูกยกเลิกการลงทะเบียนและด้วยเหตุนี้จึงเก็บรวบรวมขยะ (หากวัตถุรายการดั้งเดิมไม่ได้ถูกอ้างอิงโดยตัวแปรใด ๆ นอกเหนือจาก a)

วิธีนี้ทำให้วิธีนี้ไม่มีประสิทธิภาพมากและยังสามารถสร้างผลข้างเคียงที่ไม่พึงประสงค์ (โดยเฉพาะเมื่อตัวแปรอื่น ๆ ชี้ไปที่วัตถุรายการดั้งเดิมซึ่งยังคงไม่ถูกแก้ไข)

ขอบคุณ @MarkDickinson ที่ชี้เรื่องนี้ ...

นี้คำตอบที่กองมากเกินอธิบายแนวคิดของการหั่น

นอกจากนี้โปรดทราบว่าวิธีนี้ใช้ได้กับดัชนีที่เป็นบวกเท่านั้น

ในขณะที่ใช้กับวัตถุ__getitem__วิธีการนั้นจะต้องได้รับการกำหนดและที่สำคัญกว่านั้น__add__จะต้องมีการกำหนดวิธีการที่จะกลับวัตถุที่มีรายการจากทั้งตัวถูกดำเนินการ

ในสาระสำคัญนี้ทำงานกับวัตถุใด ๆ ที่มีความหมายระดับ:

class foo(object):
    def __init__(self, items):
        self.items = items

    def __getitem__(self, index):
        return foo(self.items[index])

    def __add__(self, right):
        return foo( self.items + right.items )

งานนี้ใช้listกำหนด__getitem__และ__add__วิธีการใด

การเปรียบเทียบทั้งสามวิธีในแง่ของประสิทธิภาพ:

สมมติว่าสิ่งต่อไปนี้ถูกกำหนดไว้ล่วงหน้า:

a = range(10)
index = 3

del object[index]วิธีการ:

โดยวิธีการที่มีประสิทธิภาพที่สุด การทำงานจะวัตถุทั้งหมดที่กำหนด__del__วิธีการ

ถอดชิ้นส่วนดังต่อไปนี้:

รหัส:

def del_method():
    global a
    global index
    del a[index]

ถอดชิ้นส่วน:

 10    0 LOAD_GLOBAL     0 (a)
       3 LOAD_GLOBAL     1 (index)
       6 DELETE_SUBSCR   # This is the line that deletes the item
       7 LOAD_CONST      0 (None)
      10 RETURN_VALUE
None

pop วิธี:

มันมีประสิทธิภาพน้อยกว่าวิธีการ del และใช้เมื่อคุณต้องการรับรายการที่ถูกลบ

รหัส:

def pop_method():
    global a
    global index
    a.pop(index)

ถอดชิ้นส่วน:

 17     0 LOAD_GLOBAL     0 (a)
        3 LOAD_ATTR       1 (pop)
        6 LOAD_GLOBAL     2 (index)
        9 CALL_FUNCTION   1
       12 POP_TOP
       13 LOAD_CONST      0 (None)
       16 RETURN_VALUE

ชิ้นและเพิ่มวิธีการ

มีประสิทธิภาพน้อยที่สุด

รหัส:

def slice_method():
    global a
    global index
    a = a[:index] + a[index+1:]

ถอดชิ้นส่วน:

 24     0 LOAD_GLOBAL    0 (a)
        3 LOAD_GLOBAL    1 (index)
        6 SLICE+2
        7 LOAD_GLOBAL    0 (a)
       10 LOAD_GLOBAL    1 (index)
       13 LOAD_CONST     1 (1)
       16 BINARY_ADD
       17 SLICE+1
       18 BINARY_ADD
       19 STORE_GLOBAL   0 (a)
       22 LOAD_CONST     0 (None)
       25 RETURN_VALUE
None

หมายเหตุ: return Noneในทั้งสามลอกละเว้นสองบรรทัดสุดท้ายซึ่งโดยทั่วไปมี นอกจากนี้ยังมีสองบรรทัดแรกมีการโหลดค่าระดับโลกและaindex


4
วิธีการแบ่งส่วนของคุณจะไม่ลบองค์ประกอบออกจากรายการ แต่จะสร้างวัตถุรายการใหม่ที่มีทั้งหมดยกเว้นรายการ ith จากรายการเดิม รายการเดิมไม่มีการแก้ไข
Mark Dickinson

@MarkDickinson ได้แก้ไขคำตอบเพื่อชี้แจงอย่างชัดเจน ... โปรดแจ้งให้เราทราบหากตอนนี้ดูดีขึ้นแล้วหรือยัง
Raghav RV

6
บางทีคำตอบอาจไม่ได้อยู่ในหัวข้อทั้งหมด แต่วิธีการจัดทำดัชนีมีประโยชน์ถ้าคุณต้องการละเว้นรายการจากวัตถุที่ไม่เปลี่ยนรูปเช่นทูเปิล pop () และ del () จะไม่ทำงานในกรณีนั้น
Caleb

6
@ rvraghav93 จากวิธีการที่นำเสนอทั้งหมดในระหว่างการโพสต์ทั้งหมดa = a[:index] + a[index+1 :]-trick เป็นวิธีที่ง่ายที่สุดเมื่อพูดถึงรายการใหญ่ ๆ วิธีการอื่นทั้งหมดจบลงด้วยการหยุดชะงัก ขอบคุณมาก
3085931

3
มาร์คแน่นอนคุณไม่พอใจ คำตอบนี้เป็นคำตอบที่ฉันชอบเพราะมันสอนได้จริง ฉันเรียนรู้มากที่สุดจากคำตอบนี้และรายละเอียดเกี่ยวกับการประกอบชิ้นส่วนที่จัดเตรียมไว้และผลกระทบต่อนักแสดง บวกกับวิธีการแบ่งส่วนสร้างวัตถุอื่น แต่ตอนนี้มันถูกระบุและบางครั้งก็เป็นสิ่งที่คุณต้องการ
Yohan Obadia

52

popยังมีประโยชน์ในการลบและเก็บรายการจากรายการ ในกรณีที่delเก็บรายการ

>>> x = [1, 2, 3, 4]

>>> p = x.pop(1)
>>> p
    2

24

หากคุณต้องการลบองค์ประกอบตำแหน่งที่เฉพาะเจาะจงในรายการเช่นที่ 2, 3 และ 7 คุณไม่สามารถใช้

del my_list[2]
del my_list[3]
del my_list[7]

เนื่องจากหลังจากที่คุณลบองค์ประกอบที่สององค์ประกอบที่สามที่คุณลบจริง ๆ แล้วคือองค์ประกอบที่สี่ในรายการเดิม คุณสามารถกรององค์ประกอบที่ 2, 3 และลำดับที่ 7 ในรายการต้นฉบับและรับรายการใหม่เช่นด้านล่าง:

new list = [j for i, j in enumerate(my_list) if i not in [2, 3, 7]]

19

ขึ้นอยู่กับสิ่งที่คุณต้องการจะทำ

หากคุณต้องการคืนองค์ประกอบที่คุณลบให้ใช้pop():

>>> l = [1, 2, 3, 4, 5]
>>> l.pop(2)
3
>>> l
[1, 2, 4, 5]

อย่างไรก็ตามหากคุณต้องการลบองค์ประกอบให้ใช้del:

>>> l = [1, 2, 3, 4, 5]
>>> del l[2]
>>> l
[1, 2, 4, 5]

นอกจากนี้ยังdelช่วยให้คุณใช้งานชิ้น (เช่นdel[2:])


18

โดยทั่วไปฉันใช้วิธีการดังต่อไปนี้:

>>> myList = [10,20,30,40,50]
>>> rmovIndxNo = 3
>>> del myList[rmovIndxNo]
>>> myList
[10, 20, 30, 50]

15

อีกวิธีหนึ่งในการลบองค์ประกอบจากรายการโดยดัชนี

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# remove the element at index 3
a[3:4] = []
# a is now [0, 1, 2, 4, 5, 6, 7, 8, 9]

# remove the elements from index 3 to index 6
a[3:7] = []
# a is now [0, 1, 2, 7, 8, 9]

a [x: Y] จุดกับองค์ประกอบจากดัชนีการx y-1เมื่อเราประกาศส่วนของรายการว่าเป็นรายการว่างเปล่า ( []) องค์ประกอบเหล่านั้นจะถูกลบออก


14

คุณสามารถค้นหารายการที่คุณต้องการลบ มันง่ายจริงๆ ตัวอย่าง:

    letters = ["a", "b", "c", "d", "e"]
    letters.remove(letters[1])
    print(*letters) # Used with a * to make it unpack you don't have to (Python 3.x or newer)

เอาท์พุท: acde


6
ฉันชอบโซลูชันนี้ แต่แน่นอนว่ารายการของคุณจะไม่ซ้ำซ้อน
tommy.carstensen

11

ใช้รหัสต่อไปนี้เพื่อลบองค์ประกอบออกจากรายการ:

list = [1, 2, 3, 4]
list.remove(1)
print(list)

output = [2, 3, 4]

หากคุณต้องการลบข้อมูลองค์ประกอบดัชนีจากการใช้รายการ:

list = [1, 2, 3, 4]
list.remove(list[2])
print(list)
output : [1, 2, 4]

2
มาพร้อมกับข้อแม้ที่รายการของคุณไม่สามารถมีรายการที่ซ้ำกัน
tommy.carstensen

3
สิ่งนี้ไม่ได้ถูกลบโดยดัชนี แต่เป็นการลบโดยค่าที่ตรงกัน นั่นอาจเป็นข้อมูลที่มีค่าสำหรับบางคนที่มาที่นี่ แต่ไม่ลองตอบคำถาม OPs เลย
Anthon

8

วิธีปฏิบัติที่ดีที่สุดคือ del (); หรือป๊อป () หากคุณจำเป็นต้องรู้คุณค่า

โซลูชันสำรองคือการสแต็กองค์ประกอบที่คุณต้องการอีกครั้งเท่านั้น:

    a = ['a', 'b', 'c', 'd'] 

    def remove_element(list_,index_):
        clipboard = []
        for i in range(len(list_)):
            if i is not index_:
                clipboard.append(list_[i])
        return clipboard

    print(remove_element(a,2))

    >> ['a', 'b', 'd']

กทพ.: hmm ... จะไม่ทำงานกับค่าดัชนีลบจะไตร่ตรองและอัปเดต

ฉันคิดว่า

if index_<0:index_=len(list_)+index_

จะแก้ไขมัน ... แต่ทันใดความคิดนี้ก็ดูเปราะบางมาก การทดลองทางความคิดที่น่าสนใจว่า ดูเหมือนว่าควรมีวิธีการ 'ที่ถูกต้อง' ในการทำสิ่งนี้ด้วยการผนวก () / list comprehension

ขบคิด


1
ซึ่งรุ่นของงูใหญ่มีฟังก์ชั่นdel()? สำหรับฟังก์ชั่นนั้นคุณให้รายชื่อเป็นอาร์กิวเมนต์แรกของฟังก์ชั่นนั้นและจากนั้นดัชนีหรือดัชนีแรกและจากนั้นรายการ? มันจะส่งกลับอาร์กิวเมนต์รายการโดยไม่มีรายการหรือมันจะลบในสถานที่ ฉันรู้เกี่ยวกับdelคำสั่ง แต่ไม่เกี่ยวกับฟังก์ชั่นที่มีชื่อเดียวกัน
Anthon

8

ดูเหมือนว่าคุณจะไม่ได้ทำงานกับรายชื่อรายการดังนั้นฉันจะอธิบายสั้น ๆ นี้ คุณต้องการใช้ป๊อปเนื่องจากมันจะลบองค์ประกอบที่ไม่ใช่องค์ประกอบที่เป็นรายการคุณควรใช้ del เพื่อ ในการเรียกองค์ประกอบสุดท้ายในหลามมันคือ "-1"

>>> test = ['item1', 'item2']
>>> test.pop(-1)
'item2'
>>> test
['item1']

1
pop()และdelทั้งสองลบองค์ประกอบที่ดัชนีที่ให้ไว้เป็นอิสระจากองค์ประกอบที่ว่าตัวเองเป็นรายการหรือไม่ a = [1, [2, 3], 4]; del a[1]; b = [1, [2, 3], 4]; b.pop(1); assert a == b
Anthon

8

l - รายการค่า; เราต้องลบดัชนีออกจากรายการinds2rem

l = range(20)
inds2rem = [2,5,1,7]
map(lambda x: l.pop(x), sorted(inds2rem, key = lambda x:-x))

>>> l
[0, 3, 4, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

<map at 0x7f4d54109a58>ทำงานไม่คำตอบคือ และ l คือช่วง (0,20)
Hitesh

7

ใช้ฟังก์ชั่น"del" :

del listName[-N]

ตัวอย่างเช่นหากคุณต้องการลบ 3 รายการสุดท้ายรหัสของคุณควรเป็น:

del listName[-3:]

ตัวอย่างเช่นหากคุณต้องการลบ 8 รายการสุดท้ายรหัสของคุณควรเป็น:

del listName[-8:]

2
delเป็นคำสั่ง ถ้ามันเป็นฟังก์ชั่นคุณจะต้องเขียนdel(listame[-N])
Anthon

7

มันได้รับการกล่าวถึงวิธีการลบองค์ประกอบเดียวจากรายการและข้อได้เปรียบที่วิธีการต่าง ๆ มี อย่างไรก็ตามโปรดทราบว่าการลบองค์ประกอบหลายรายการมีข้อผิดพลาด:

>>> l = [0,1,2,3,4,5,6,7,8,9]
>>> indices=[3,7]
>>> for i in indices:
...     del l[i]
... 
>>> l
[0, 1, 2, 4, 5, 6, 7, 9]

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

>>> l = [0,1,2,3,4,5,6,7,8,9]
>>> indices=[3,7]
>>> for i in sorted(indices, reverse=True):
...     del l[i]
... 
>>> l
[0, 1, 2, 4, 5, 6, 8, 9]

4

หรือถ้าควรลบดัชนีหลายรายการ:

print([v for i,v in enumerate(your_list) if i not in list_of_unwanted_indexes])

แน่นอนว่ายังสามารถทำได้:

print([v for i,v in enumerate(your_list) if i != unwanted_index])

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

3

คุณสามารถใช้เดลหรือป๊อปเพื่อลบองค์ประกอบออกจากรายการตามดัชนี ป๊อปจะพิมพ์สมาชิกที่ถูกลบออกจากรายการในขณะที่รายการจะลบสมาชิกนั้นโดยไม่พิมพ์

>>> a=[1,2,3,4,5]
>>> del a[1]
>>> a
[1, 3, 4, 5]
>>> a.pop(1)
 3
>>> a
[1, 4, 5]
>>> 

3

หนึ่งสามารถใช้เดลหรือป๊อป แต่ฉันชอบเดลเนื่องจากคุณสามารถระบุดัชนีและชิ้นส่วนทำให้ผู้ใช้สามารถควบคุมข้อมูลได้มากขึ้น

ยกตัวอย่างเช่นเริ่มต้นด้วยรายการที่แสดงหนึ่งสามารถลบองค์ประกอบสุดท้ายกับเป็นชิ้นแล้วใครสามารถลบองค์ประกอบสุดท้ายจากผลที่ได้ใช้delpop

>>> l = [1,2,3,4,5]
>>> del l[-1:]
>>> l
[1, 2, 3, 4]
>>> l.pop(-1)
4
>>> l
[1, 2, 3]
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.