การลบองค์ประกอบหลายรายการจากรายการ


160

เป็นไปได้ไหมที่จะลบองค์ประกอบหลายรายการจากรายการในเวลาเดียวกัน? หากฉันต้องการลบองค์ประกอบที่ดัชนี 0 และ 2 และลองทำdel somelist[0]ตามชอบแล้วdel somelist[2]ข้อความที่สองจะลบออกจริงsomelist[3]

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

คำตอบ:


110

อาจไม่ใช่วิธีแก้ปัญหาที่ดีที่สุดสำหรับปัญหานี้:

indices = 0, 2
somelist = [i for j, i in enumerate(somelist) if j not in indices]

2
เกือบเฉพาะเมื่อคุณลบรายการทั้งหมด มันจะเป็น len (ดัชนี) * len (somelist) นอกจากนี้ยังสร้างสำเนาซึ่งอาจจะหรืออาจจะไม่เป็นที่ต้องการ
ริชาร์ด Levasseur

หากคุณกำลังตรวจสอบค่าในรายการนั่นก็คือ ตัวดำเนินการ 'in' ทำงานกับค่าของรายการในขณะที่ทำงานบนคีย์ของ dict หากฉันผิดโปรดชี้ให้ฉันไปที่ห้าวหาญ / อ้างอิง
Richard Levasseur

5
เหตุผลที่ฉันเลือก tuple สำหรับดัชนีเป็นเพียงความเรียบง่ายของการบันทึก มันจะเป็นงานที่สมบูรณ์แบบสำหรับการตั้งค่า () ให้ O (n)
SilentGhost

18
นี่ไม่ใช่การลบรายการออกจากรายการที่ต้องทำทั้งหมด แต่เป็นการสร้างรายการใหม่ หากมีสิ่งใดที่อ้างอิงถึงรายการดั้งเดิมมันจะยังคงมีรายการทั้งหมดอยู่ในนั้น
Tom Future

2
@SilentGhost ไม่จำเป็นต้องทำการนับ วิธีการเกี่ยวกับเรื่องนี้: somelist = [ lst[i] for i in xrange(len(lst)) if i not in set(indices) ]?
ToolmakerSteve

183

ด้วยเหตุผลบางอย่างฉันไม่ชอบคำตอบใด ๆ ที่นี่ ใช่มันใช้งานได้ แต่การพูดอย่างเคร่งครัดส่วนใหญ่ไม่ได้ลบองค์ประกอบในรายการใช่ไหม (แต่การทำสำเนาแล้วแทนที่ต้นฉบับด้วยสำเนาที่แก้ไข)

ทำไมไม่เพียงลบดัชนีที่สูงขึ้นก่อน?

มีเหตุผลสำหรับสิ่งนี้หรือไม่? ฉันแค่จะทำ:

for i in sorted(indices, reverse=True):
    del somelist[i]

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

ฉันทำอะไรบางอย่างหายไปที่นี่เหตุผลใดที่จะไม่ลบในลำดับย้อนกลับ?


1
ฉันไม่รู้ว่าทำไมสิ่งนี้จึงไม่ถูกเลือกเป็นคำตอบที่ยอมรับ! ขอบคุณสำหรับสิ่งนี้.
swathis

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

1
@ImperishableNight คุณจะอธิบายอย่างละเอียดหรือไม่? ฉันไม่เข้าใจ "องค์ประกอบบางอย่างจำเป็นต้องเปลี่ยน" สำหรับ (b) คุณสามารถกำหนดฟังก์ชั่นได้ถ้าคุณต้องการความชัดเจนในการอ่าน
tglaria

109

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

หากรายการของคุณอยู่ติดกันคุณสามารถใช้ไวยากรณ์การกำหนดชิ้น:

a[2:10] = []

95
คุณสามารถพูดdel a[2:10]ด้วยเอฟเฟกต์เดียวกันได้
sth

8
@sth น่าสนใจ del เร็วกว่าการกำหนดเล็กน้อย
thefourtheye

24

คุณสามารถใช้numpy.deleteดังนี้

import numpy as np
a = ['a', 'l', 3.14, 42, 'u']
I = [0, 2]
np.delete(a, I).tolist()
# Returns: ['l', '42', 'u']

หากคุณไม่ทราบสิ้นสุดกับอาร์เรย์ในตอนท้ายคุณสามารถปล่อยให้ออกnumpy .tolist()คุณควรเห็นการปรับปรุงความเร็วที่สำคัญบางอย่างเช่นกันทำให้นี่เป็นโซลูชันที่ปรับขนาดได้มากขึ้น ฉันไม่ได้ทำการเปรียบเทียบ แต่numpyการคอมไพล์โค้ดที่เขียนใน C หรือ Fortran


1
วิธีการแก้ปัญหาทั่วไปเมื่อองค์ประกอบไม่ต่อเนื่อง +1
noɥʇʎԀʎzɐɹƆ

1
คำถามที่นี่วิธีการลบ ['a', 42]
evanhutomo

คะแนนโบนัสขนาดใหญ่สำหรับโซลูชันนี้เมื่อเทียบกับคะแนนอื่น ๆ สำหรับความเร็ว สิ่งที่ฉันสามารถพูดได้คือสำหรับชุดข้อมูลที่มีขนาดใหญ่มากฉันใช้เวลาหลายนาทีในการทำสิ่งที่ใช้เวลาเพียงไม่กี่วินาทีด้วยความรู้สึกที่ดี
legel

18

ในฐานะที่เป็นคำตอบเฉพาะของ Greg คุณสามารถใช้ไวยากรณ์ส่วนขยายเพิ่มเติมได้ เช่น. หากคุณต้องการลบรายการ 0 และ 2:

>>> a= [0, 1, 2, 3, 4]
>>> del a[0:3:2]
>>> a
[1, 3, 4]

สิ่งนี้ไม่ครอบคลุมถึงการเลือกโดยพลการใด ๆ แต่มันสามารถใช้ลบสองรายการได้


16

ในฐานะที่เป็นฟังก์ชั่น:

def multi_delete(list_, *args):
    indexes = sorted(list(args), reverse=True)
    for index in indexes:
        del list_[index]
    return list_

รันในเวลาn log (n)ซึ่งควรทำให้เป็นโซลูชันที่ถูกต้องเร็วที่สุด


1
รุ่นที่มี args.sort (). reverse () ดีกว่าแน่นอน นอกจากนี้ยังเกิดขึ้นกับการทำงานกับ dicts แทนที่จะโยนหรือเลวร้ายลงทำให้เสียหายอย่างเงียบ ๆ

sort () ไม่ได้ถูกกำหนดไว้สำหรับ tuple คุณต้องแปลงเป็น list ก่อน sort () ส่งคืน None ดังนั้นคุณไม่สามารถใช้ reverse () กับมันได้
SilentGhost

@ R. Pate: ฉันลบเวอร์ชันแรกด้วยเหตุผลนั้น ขอบคุณ @ SilentGhost: แก้ไข
Nikhil Chelliah

@Nikhil: ไม่คุณไม่ได้;) args = รายการ (args) args.sort () args.reverse () แต่ตัวเลือกที่ดีกว่าจะเป็น: args = เรียงลำดับ (args, reverse = True)
SilentGhost

2
n log n? จริงๆ? ฉันไม่คิดว่าdel list[index]เป็น O (1)
user202729

12

ดังนั้นคุณต้องการลบองค์ประกอบหลายรายการในรอบเดียวหรือไม่? ในกรณีนั้นตำแหน่งขององค์ประกอบถัดไปที่จะลบจะถูกชดเชยด้วยจำนวนที่ถูกลบไปก่อนหน้านี้

เป้าหมายของเราคือการลบเสียงสระทั้งหมดซึ่งถูกคำนวณไว้ล่วงหน้าเป็นดัชนี 1, 4 และ 7 โปรดทราบว่าสิ่งสำคัญคือดัชนี to_delete นั้นเรียงลำดับจากน้อยไปมากมิฉะนั้นมันจะไม่ทำงาน

to_delete = [1, 4, 7]
target = list("hello world")
for offset, index in enumerate(to_delete):
  index -= offset
  del target[index]

มันจะซับซ้อนกว่านี้ถ้าคุณต้องการลบองค์ประกอบในลำดับใด ๆ IMO เรียงลำดับอาจจะง่ายกว่าการหาเมื่อคุณควรหรือไม่ควรลบออกจากto_deleteindex


8

ฉันเป็นผู้เริ่มต้นทั้งหมดใน Python และการเขียนโปรแกรมของฉันในขณะนี้คือหยาบและสกปรกที่จะพูดน้อย แต่วิธีการแก้ปัญหาของฉันคือการใช้ชุดคำสั่งพื้นฐานที่ฉันได้เรียนรู้จากบทเรียนเบื้องต้น:

some_list = [1,2,3,4,5,6,7,8,10]
rem = [0,5,7]

for i in rem:
    some_list[i] = '!' # mark for deletion

for i in range(0, some_list.count('!')):
    some_list.remove('!') # remove
print some_list

เห็นได้ชัดว่าเนื่องจากต้องเลือกอักขระ "การลบเครื่องหมาย" จึงมีข้อ จำกัด

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


2
แทนที่จะใช้ '!' เป็นอักขระพิเศษของคุณใช้ไม่มี สิ่งนี้จะช่วยให้ตัวละครทุกตัวมีชีวิตที่ถูกต้องและปลดปล่อยความเป็นไปได้ของคุณ
portforwardpodcast

5

นี่เป็นอีกทางเลือกหนึ่งที่ไม่ได้ใช้แจกแจง () เพื่อสร้างสิ่งอันดับ (เช่นเดียวกับคำตอบดั้งเดิมของ SilentGhost)

ดูเหมือนว่าฉันจะอ่านได้มากกว่านี้ (บางทีฉันอาจจะรู้สึกแตกต่างถ้าฉันใช้นิสัยในการแจกแจง) CAVEAT: ฉันไม่ได้ทดสอบประสิทธิภาพของทั้งสองวิธี

# Returns a new list. "lst" is not modified.
def delete_by_indices(lst, indices):
    indices_as_set = set(indices)
    return [ lst[i] for i in xrange(len(lst)) if i not in indices_as_set ]

หมายเหตุ: ไวยากรณ์ Python 2.7 สำหรับงูหลาม 3 =>xrangerange

การใช้งาน:

lst = [ 11*x for x in xrange(10) ]
somelist = delete_by_indices( lst, [0, 4, 5])

somelist:

[11, 22, 33, 66, 77, 88, 99]

--- โบนัส ---

ลบค่าหลายค่าจากรายการ นั่นคือเรามีค่าที่เราต้องการลบ:

# Returns a new list. "lst" is not modified.
def delete__by_values(lst, values):
    values_as_set = set(values)
    return [ x for x in lst if x not in values_as_set ]

การใช้งาน:

somelist = delete__by_values( lst, [0, 44, 55] )

somelist:

[11, 22, 33, 66, 77, 88, 99]

นี่เป็นคำตอบเดียวกับเมื่อก่อน แต่คราวนี้เราให้ค่าที่ถูกลบ[0, 44, 55]ไป


ฉันตัดสินใจว่า @ SilentGhost นั้นอ่านยากเท่านั้นเพราะชื่อตัวแปรที่ไม่ใช่คำอธิบายที่ใช้สำหรับผลลัพธ์ของการแจกแจง ยิ่งไปกว่านั้น parens จะทำให้อ่านง่ายขึ้น ดังนั้นนี่คือวิธีการที่ฉันจะคำแก้ปัญหาของเขา (กับ "ชุด" [ value for (i, value) in enumerate(lst) if i not in set(indices) ]เพิ่มสำหรับการทำงาน): แต่ฉันจะทิ้งคำตอบไว้ที่นี่เพราะฉันยังแสดงวิธีการลบโดยค่า ซึ่งเป็นกรณีที่ง่ายกว่า แต่อาจช่วยใครบางคน
ToolmakerSteve

@ Veedrac- ขอบคุณ; ฉันเขียนใหม่เพื่อสร้างชุดแรก คุณคิดอย่างไร - เร็วกว่าโซลูชันของ SilentGhost (ผมไม่คิดว่ามันเป็นสิ่งสำคัญที่จะพอที่จริงเวลามันเป็นเพียงแค่การถามความคิดเห็นของคุณ.) ในทำนองเดียวกันผมจะเขียนใหม่รุ่น SilentGhost เป็นindices_as_set = set(indices), [ value for (i, value) in enumerate(lst) if i not in indices_as_set ]เพื่อเพิ่มความเร็วขึ้น
ToolmakerSteve

มีเหตุผลสไตล์สำหรับขีดเส้นใต้สองครั้งdelete__by_values()หรือไม่?
ทอม

5

วิธีรายการความเข้าใจทางเลือกที่ใช้ค่าดัชนีรายการ:

stuff = ['a', 'b', 'c', 'd', 'e', 'f', 'woof']
index = [0, 3, 6]
new = [i for i in stuff if stuff.index(i) not in index]

ผลตอบแทนนี้:

['b', 'c', 'e', 'f']

คำตอบที่ดี แต่การตั้งชื่อรายการดัชนีตามที่indexเข้าใจผิดเนื่องจากใน iterator รายการใช้วิธีการindex()
Joe

4

นี่คือวิธีการอีกวิธีหนึ่งที่จะลบองค์ประกอบต่างๆ ถ้ารายการของคุณยาวจริงๆมันเร็วกว่า

>>> a = range(10)
>>> remove = [0,4,5]
>>> from collections import deque
>>> deque((list.pop(a, i) for i in sorted(remove, reverse=True)), maxlen=0)

>>> timeit.timeit('[i for j, i in enumerate(a) if j not in remove]', setup='import random;remove=[random.randrange(100000) for i in range(100)]; a = range(100000)', number=1)
0.1704120635986328

>>> timeit.timeit('deque((list.pop(a, i) for i in sorted(remove, reverse=True)), maxlen=0)', setup='from collections import deque;import random;remove=[random.randrange(100000) for i in range(100)]; a = range(100000)', number=1)
0.004853963851928711

+1: การใช้ deque เพื่อทำการกระทำที่น่าสนใจเป็นส่วนหนึ่งของนิพจน์แทนที่จะต้องใช้บล็อก "for .. :" อย่างไรก็ตามสำหรับกรณีนี้ฉันพบว่า Nikhil ใช้บล็อกที่อ่านง่ายขึ้น
ToolmakerSteve

4

เรื่องนี้ได้รับการกล่าวถึง แต่อย่างใดไม่มีใครจัดการเพื่อทำให้ถูกต้องจริง

ในการO(n)แก้ปัญหาจะเป็น:

indices = {0, 2}
somelist = [i for j, i in enumerate(somelist) if j not in indices]

นี่ใกล้เคียงกับเวอร์ชั่นของ SilentGhostแต่เพิ่มเครื่องหมายวงเล็บสองอัน


นี่ไม่ใช่O(n)ถ้าคุณนับการค้นหาที่ใช้log(len(indices))สำหรับการวนซ้ำแต่ละครั้ง
นักฟิสิกส์บ้า

@MadPhysicist คือj not in indices O(1)
Veedrac

ฉันไม่แน่ใจว่าคุณได้รับหมายเลขนั้นได้อย่างไร เนื่องจากดัชนีเป็นชุดยังคงต้องค้นหาซึ่งเป็นj not in indices O(log(len(indices)))ในขณะที่ผมยอมรับว่าการค้นหาในชุดที่ 2 องค์ประกอบที่มีคุณสมบัติเป็นในกรณีทั่วไปมันจะเป็นO(1) O(log(N))ทั้งสองวิธีเต้นยังคงO(N log(N)) O(N^2)
นักฟิสิกส์บ้า


และเครื่องมือจัดฟันสองอันทำอะไรกันแน่
Nuclear03020704

4
l = ['a','b','a','c','a','d']
to_remove = [1, 3]
[l[i] for i in range(0, len(l)) if i not in to_remove])

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


2

วิธีการลบจะทำให้เกิดการเปลี่ยนแปลงองค์ประกอบรายการจำนวนมาก ฉันคิดว่าดีกว่าที่จะทำสำเนา:

...
new_list = []
for el in obj.my_list:
   if condition_is_true(el):
      new_list.append(el)
del obj.my_list
obj.my_list = new_list
...

2

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

del (foo['bar'],foo['baz'])

จะลบซ้ำfoo['bar']อีกครั้งfoo['baz']


การลบนี้ออกจากวัตถุ dict ไม่ใช่รายการ แต่ฉันยังคง +1 เพราะทำให้มันน่ารัก
Ulf Aslak

มันใช้กับรายการเช่นกันกับไวยากรณ์ที่เหมาะสม อย่างไรก็ตามการอ้างสิทธิ์คือมันเป็นไปไม่ได้ที่จะลบสองวัตถุในเวลาเดียวกันเป็นเท็จ ดูคำตอบโดย @bobince
Pedro Gimeno

2

เราสามารถทำได้โดยใช้การวนซ้ำวนรอบดัชนีหลังจากเรียงลำดับรายการดัชนีตามลำดับจากมากไปน้อย

mylist=[66.25, 333, 1, 4, 6, 7, 8, 56, 8769, 65]
indexes = 4,6
indexes = sorted(indexes, reverse=True)
for i in index:
    mylist.pop(i)
print mylist

2

สำหรับดัชนี 0 และ 2 จากรายการ A:

for x in (2,0): listA.pop(x)

สำหรับดัชนีสุ่มที่จะลบออกจาก listA:

indices=(5,3,2,7,0) 
for x in sorted(indices)[::-1]: listA.pop(x)

2

ฉันต้องการวิธีเปรียบเทียบโซลูชันที่แตกต่างกันซึ่งทำให้ง่ายต่อการหมุนลูกบิด

ก่อนอื่นฉันสร้างข้อมูลของฉัน:

import random

N = 16 * 1024
x = range(N)
random.shuffle(x)
y = random.sample(range(N), N / 10)

จากนั้นฉันก็นิยามฟังก์ชั่นของฉัน:

def list_set(value_list, index_list):
    index_list = set(index_list)
    result = [value for index, value in enumerate(value_list) if index not in index_list]
    return result

def list_del(value_list, index_list):
    for index in sorted(index_list, reverse=True):
        del(value_list[index])

def list_pop(value_list, index_list):
    for index in sorted(index_list, reverse=True):
        value_list.pop(index)

จากนั้นฉันก็ใช้timeitเปรียบเทียบโซลูชัน:

import timeit
from collections import OrderedDict

M = 1000
setup = 'from __main__ import x, y, list_set, list_del, list_pop'
statement_dict = OrderedDict([
    ('overhead',  'a = x[:]'),
    ('set', 'a = x[:]; list_set(a, y)'),
    ('del', 'a = x[:]; list_del(a, y)'),
    ('pop', 'a = x[:]; list_pop(a, y)'),
])

overhead = None
result_dict = OrderedDict()
for name, statement in statement_dict.iteritems():
    result = timeit.timeit(statement, number=M, setup=setup)
    if overhead is None:
        overhead = result
    else:
        result = result - overhead
        result_dict[name] = result

for name, result in result_dict.iteritems():
    print "%s = %7.3f" % (name, result)

เอาท์พุต

set =   1.711
del =   3.450
pop =   3.618

ดังนั้นเครื่องกำเนิดที่มีดัชนีใน a setจึงเป็นผู้ชนะ และเป็นเร็วขึ้นเล็กน้อยแล้วdelpop


ขอขอบคุณสำหรับการเปรียบเทียบสิ่งนี้ทำให้ฉันทำการทดสอบของตัวเอง (จริง ๆ แล้วแค่ยืมรหัสของคุณ) และสำหรับรายการเล็ก ๆ น้อย ๆ ที่จะลบค่าใช้จ่ายสำหรับการสร้าง SET ทำให้เป็นทางออกที่แย่ที่สุด (ใช้ 10, 100, 500 ความยาวของ 'y' และคุณจะเห็น) ส่วนใหญ่แล้วขึ้นอยู่กับแอปพลิเคชัน
tglaria

2

คุณสามารถใช้ตรรกะนี้:

my_list = ['word','yes','no','nice']

c=[b for i,b in enumerate(my_list) if not i in (0,2,3)]

print c

2

การดำเนินการตามแนวความคิดอื่นในการลบออกจากดัชนีสูงสุด

for i in range(len(yourlist)-1, -1, -1):
    del yourlist(i)

1

จริง ๆ แล้วฉันสามารถคิดถึงวิธีการสองวิธี:

  1. แบ่งรายการเช่น (นี่เป็นการลบองค์ประกอบที่ 1, 3 และ 8)

    somelist = somelist [1: 2] + somelist [3: 7] + somelist [8:]

  2. ทำในสถานที่ แต่หนึ่งครั้ง:

    somelist.pop (2) somelist.pop (0)


1

คุณสามารถทำเช่นนั้นกับ dict ไม่ใช่ในรายการ ในองค์ประกอบรายการอยู่ในลำดับ ใน dict พวกเขาขึ้นอยู่กับดัชนีเท่านั้น

รหัสง่าย ๆ เพียงอธิบายโดยทำ :

>>> lst = ['a','b','c']
>>> dct = {0: 'a', 1: 'b', 2:'c'}
>>> lst[0]
'a'
>>> dct[0]
'a'
>>> del lst[0]
>>> del dct[0]
>>> lst[0]
'b'
>>> dct[0]
Traceback (most recent call last):
  File "<pyshell#19>", line 1, in <module>
    dct[0]
KeyError: 0
>>> dct[1]
'b'
>>> lst[1]
'c'

วิธีการ "แปลง" รายการใน dict คือ:

>>> dct = {}
>>> for i in xrange(0,len(lst)): dct[i] = lst[i]

สิ่งที่ตรงกันข้ามคือ:

lst = [dct[i] for i in sorted(dct.keys())] 

อย่างไรก็ตามฉันคิดว่าเป็นการดีกว่าที่จะเริ่มต้นการลบจากดัชนีที่สูงขึ้นตามที่คุณพูด


Python รับประกัน [dct [i] สำหรับ i in dct] จะใช้ค่าที่เพิ่มขึ้นของ i หรือไม่? ถ้าเป็นเช่นนั้นรายการ (dct.values ​​()) จะดีกว่าแน่นอน

ฉันไม่ได้คิดถึงเรื่องนั้น คุณถูก. ไม่รับประกันว่าเมื่อฉันอ่าน [ที่นี่] [1] ว่ารายการจะถูกเลือกตามลำดับหรืออย่างน้อยก็เป็นไปตามลำดับที่คาดไว้ ฉันแก้ไข [1]: docs.python.org/library/stdtypes.html#dict.items
Andrea Ambu

2
คำตอบนี้พูดถึงพจนานุกรมในทางที่ผิด พจนานุกรมมี KEYS (ไม่ใช่ดัชนี) ใช่คู่ของคีย์ / ค่าเป็นอิสระจากกัน ไม่ไม่สำคัญว่าคุณจะลบรายการในลำดับใดการแปลงเป็นพจนานุกรมเพียงเพื่อลบองค์ประกอบบางอย่างออกจากรายการจะเป็นการใช้งานมากเกินไป
ToolmakerSteve

1

ที่จะพูดคุยแสดงความคิดเห็นจาก@sth การลบไอเท็มในคลาสใด ๆ ที่ใช้abc.MutableSequenceและlistโดยเฉพาะอย่างยิ่งทำได้ด้วย__delitem__วิธีเวทย์มนตร์ วิธีนี้ใช้งานได้คล้ายกับ__getitem__ความหมายซึ่งสามารถรับได้ทั้งจำนวนเต็มหรือชิ้น นี่คือตัวอย่าง:

class MyList(list):
    def __delitem__(self, item):
        if isinstance(item, slice):
            for i in range(*item.indices(len(self))):
                self[i] = 'null'
        else:
            self[item] = 'null'


l = MyList(range(10))
print(l)
del l[5:8]
print(l)

สิ่งนี้จะออก

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 'null', 'null', 'null', 8, 9]

1

การนำเข้าเฉพาะด้วยเหตุผลนี้อาจทำให้เกินกำลัง แต่ถ้าคุณบังเอิญใช้งาน pandasวิธีแก้ปัญหานั้นง่ายและตรงไปตรงมา:

import pandas as pd
stuff = pd.Series(['a','b','a','c','a','d'])
less_stuff = stuff[stuff != 'a']  # define any condition here
# results ['b','c','d']


0

อย่างใดอย่างหนึ่งเกี่ยวกับสิ่งเหล่านี้ (ฉันใหม่มากกับงูใหญ่ แต่พวกเขาดูเหมือนตกลง):

ocean_basin = ['a', 'Atlantic', 'Pacific', 'Indian', 'a', 'a', 'a']
for i in range(1, (ocean_basin.count('a') + 1)):
    ocean_basin.remove('a')
print(ocean_basin)

['แอตแลนติก', 'แปซิฟิก', 'อินเดีย']

ob = ['a', 'b', 4, 5,'Atlantic', 'Pacific', 'Indian', 'a', 'a', 4, 'a']
remove = ('a', 'b', 4, 5)
ob = [i for i in ob if i not in (remove)]
print(ob)

['แอตแลนติก', 'แปซิฟิก', 'อินเดีย']


0

ไม่มีคำตอบใดที่เสนอให้ทำการลบใน O (n) ที่ความยาวของรายการเพื่อลบดัชนีโดยพลการดังนั้นนี่คือรุ่นของฉัน:

def multi_delete(the_list, indices):
    assert type(indices) in {set, frozenset}, "indices must be a set or frozenset"
    offset = 0
    for i in range(len(the_list)):
        if i in indices:
            offset += 1
        elif offset:
            the_list[i - offset] = the_list[i]
    if offset:
        del the_list[-offset:]

# Example:
a = [0, 1, 2, 3, 4, 5, 6, 7]
multi_delete(a, {1, 2, 4, 6, 7})
print(a)  # prints [0, 3, 5]

0

คุณสามารถใช้การลบได้เช่นกัน

delete_from_somelist = []
for i in [int(0), int(2)]:
     delete_from_somelist.append(somelist[i])
for j in delete_from_somelist:
     newlist = somelist.remove(j)

0

ฉันรวบรวมมันทั้งหมดไว้ในlist_diffฟังก์ชั่นที่รับเพียงสองรายการเป็นอินพุตและคืนค่าความแตกต่างขณะเดียวกันก็รักษาลำดับดั้งเดิมของรายการแรก

def list_diff(list_a, list_b, verbose=False):

    # returns a difference of list_a and list_b,
    # preserving the original order, unlike set-based solutions

    # get indices of elements to be excluded from list_a
    excl_ind = [i for i, x in enumerate(list_a) if x in list_b]
    if verbose:
        print(excl_ind)

    # filter out the excluded indices, producing a new list 
    new_list = [i for i in list_a if list_a.index(i) not in excl_ind]
    if verbose:
        print(new_list)

    return(new_list)

ตัวอย่างการใช้งาน:

my_list = ['a', 'b', 'c', 'd', 'e', 'f', 'woof']
# index = [0, 3, 6]

# define excluded names list
excl_names_list = ['woof', 'c']

list_diff(my_list, excl_names_list)
>> ['a', 'b', 'd', 'e', 'f']
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.