มีวิธีง่าย ๆ ในการลบองค์ประกอบรายการตามค่าหรือไม่


942
a = [1, 2, 3, 4]
b = a.index(6)

del a[b]
print(a)

ด้านบนแสดงข้อผิดพลาดต่อไปนี้:

Traceback (most recent call last):
  File "D:\zjm_code\a.py", line 6, in <module>
    b = a.index(6)
ValueError: list.index(x): x not in list

ดังนั้นฉันต้องทำสิ่งนี้:

a = [1, 2, 3, 4]

try:
    b = a.index(6)
    del a[b]
except:
    pass

print(a)

แต่ไม่มีวิธีที่ง่ายกว่านี้หรือไม่


14
คุณคำนวณดัชนี 6 ในรายการของคุณ แต่ 6 ไม่อยู่ในรายการของคุณ ... แล้วจะเกิดอะไรขึ้น? :)
Johannes Charra

5
สิ่งนี้ไม่เกี่ยวกับการลบค่าในรายการเนื่องจากรหัสของคุณไม่ถึงคำสั่ง del บางทีคุณควร retitle มัน "ฉันจะได้รับดัชนีของค่าที่ไม่ได้อยู่ในรายการคำตอบที่ชัดเจน - คุณทำไม่ได้
Dave Kirby

57
@Dave ดีไม่ได้จริงๆ เขาต้องการลบรายการออกจากรายการโดยไม่คำนึงว่ามีอยู่หรือไม่ไม่ได้รับดัชนีสำหรับรายการที่ไม่มีอยู่ คำถามที่ถามกัน
ibz

ข้างจุด แต่เปลือยexceptคือการปฏิบัติที่ไม่ดี ใช้except Exceptionอย่างน้อยที่สุด
wjandrea

คำตอบ:


1564

ในการลบองค์ประกอบที่เกิดขึ้นครั้งแรกในรายการเพียงใช้list.remove:

>>> a = ['a', 'b', 'c', 'd']
>>> a.remove('b')
>>> print(a)
['a', 'c', 'd']

โปรดทราบว่าจะไม่ลบองค์ประกอบทั้งหมดที่เกิดขึ้น ใช้รายการความเข้าใจสำหรับสิ่งนั้น

>>> a = [10, 20, 30, 40, 20, 30, 40, 20, 70, 20]
>>> a = [x for x in a if x != 20]
>>> print(a)
[10, 30, 40, 30, 40, 70]

144
ล้มเหลวหากองค์ประกอบไม่ได้อยู่ในรายการ :)
ibz

21
@ibz รายการความเข้าใจไม่ล้มเหลวแม้ว่าองค์ประกอบที่ไม่ได้อยู่ในรายการมันได้หรือไม่
IsaacS

76
ในการชี้แจงให้ทุกคนทราบว่ามีการ skimming มัน "ล้มเหลว" ในแง่ที่ทำให้เกิดข้อยกเว้น ValueError
Casey Falk

10
ความเข้าใจในรายการเปลี่ยนการอ้างอิงรายการดังนั้นหากมีสำเนาของการอ้างอิงอยู่ที่ใดที่หนึ่งการลบจะไม่ติดตาม
เซบาสเตียน

ความซับซ้อนของremoveมันคืออะไร O (n)?
Rasmi Ranjan Nayak

184

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

if c in a:
    a.remove(c)

หรือ:

try:
    a.remove(c)
except ValueError:
    pass

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


9
การป้องกันดีกว่ารักษา หากคุณสามารถตรวจสอบเงื่อนไขพิเศษก่อน (ตัวอย่าง a) คุณควร
Gusdor

82
ในขณะนี้เป็นจริงในภาษาอื่น ๆ ใน Python มันเป็น "ง่ายกว่าที่จะขอการให้อภัยกว่าได้รับอนุญาต" docs.python.org/2/glossary.html#term-eafp
Dave Webb

6
@Gusdor: หากมีการแชร์รายการระหว่างเธรดa.remove(c)อาจจะล้มเหลวได้แม้จะมีการif c in aตรวจสอบ ( aสามารถแก้ไขในเธรดอื่นหลังจากการc in aตรวจสอบ แต่ก่อนการa.remove(c)โทร) try/exceptหรือล็อคสามารถใช้เพื่อหลีกเลี่ยงสภาพการแข่งขัน
jfs

7
@JFSebastian หากมีการแบ่งปันรายการระหว่างเธรดและคุณไม่ได้ใช้ส่วนที่สำคัญคุณจะมีปัญหาใหญ่
Gusdor

4
@Gusdor, Pythonique เป็นสำนวนที่ต้องลองโดยไม่ตรวจสอบและตรวจจับยกเว้นถ้ามันเกิดขึ้น มันมีประสิทธิภาพมากขึ้น (การค้นหาเพียงครั้งเดียวแทนที่จะเป็นสองการค้นหา) แม้ว่าจะขี้เหร่นิดหน่อย
Jeet

80

คุณทำได้

a=[1,2,3,4]
if 6 in a:
    a.remove(6)

แต่ข้างต้นจำเป็นต้องค้นหา 6 ในรายการ 2 ครั้งดังนั้นลองยกเว้นจะเร็วกว่า

try:
    a.remove(6)
except:
    pass

55

พิจารณา:

a = [1,2,2,3,4,5]

ในการกำจัดสิ่งที่เกิดขึ้นทั้งหมดคุณสามารถใช้ฟังก์ชันตัวกรองในไพ ธ อน ตัวอย่างเช่นมันจะมีลักษณะ:

a = list(filter(lambda x: x!= 2, a))

a != 2ดังนั้นจึงจะทำให้องค์ประกอบทั้งหมดของ

เมื่อต้องการใช้รายการใดรายการหนึ่งที่ใช้งานอยู่

a.remove(2)

ทำไมคุณห่อfilter()อื่นlist()? ตามคู่มือแล้วจะส่งคืนรายการแล้ว
Olaf Dietsche

8
@OlafDietsche ใน Python 3.x จะส่งคืนวัตถุตัวกรอง (ใน 2.x จะส่งคืนรายการ) ดังนั้นฉันต้องส่ง "a" ไปยังรายการเพื่อให้มีฟังก์ชั่นใด ๆ
mathwizurd

17

ต่อไปนี้เป็นวิธีเข้าแทนที่ (โดยไม่มีความเข้าใจในรายการ):

def remove_all(seq, value):
    pos = 0
    for item in seq:
        if item != value:
           seq[pos] = item
           pos += 1
    del seq[pos:]

ฉลาดมาก - ฉันชอบสิ่งนี้มาก - น่าเสียดายที่คำตอบที่ได้รับความนิยมมากที่สุดดูเหมือนจะไร้ประสิทธิภาพ วิธีการแก้ปัญหาของ gil นั้นเร็วกว่ามากสำหรับรายการยักษ์ที่มีค่าที่คุณต้องการลบเพียงไม่กี่ครั้ง
Larold

1
@Larold วิธีที่เร็วที่สุดจะเป็นคำถามแยกต่างหาก เงินของฉันอยู่ในรายการความเข้าใจในกรณีทั่วไป วิธีการแก้ปัญหานี้ควรทำงานได้ดีถ้าค่าเป็นประจำในรายการอินพุตและไม่เข้าใจการใช้รายการ ลอง Pypy ซึ่งเป็นข้อมูลที่มีค่าใน Cython [คำตอบของ @ Gill นั้นO(n*n)ไม่จำเป็น (เปรียบเทียบ 1e6 และ 1e12 - คุณไม่ต้องการเสี่ยงหลัง) while 1: L.remove(value)และผลตอบแทนValueErrorอาจทำงานได้ดีกับบาง valueรายการหรือรายการเล็ก ๆ ใน CPython
jfs

13

หากคุณรู้ว่าควรลบค่าใดต่อไปนี้เป็นวิธีที่ง่าย (เรียบง่ายอย่างที่ฉันนึกออก)

a = [0, 1, 1, 0, 1, 2, 1, 3, 1, 4]
while a.count(1) > 0:
    a.remove(1)

คุณจะได้รับ [0, 0, 2, 3, 4]


4
ทำไมไม่ใช้while 1 in a:เป็นโครงสร้างลูป?
TerminalDilettante

12
นี้เป็นที่เข้าใจจะเป็นO(n^2) O(n)
นักฟิสิกส์บ้า

1
แน่นอน @MadPhysicist นั้นถูกต้องและเวอร์ชั่น TerminalDilettante นั้นมีความไพเราะมากกว่าเดิมแม้ว่าเราจะไม่สนใจประสิทธิภาพก็ตาม ปี 2556 ฉันเพิ่งเริ่มเรียนรู้ Python และทุกวันนี้ฉันค่อนข้างละอายใจกับสิ่งที่ฉันเขียนตอนนั้น
gil

11

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

IE หากข้อมูลของคุณไม่ได้รับคำสั่งและไม่มีการซ้ำซ้อน

my_set=set([3,4,2])
my_set.discard(1)

ปราศจากข้อผิดพลาด

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

my_set.add(3)

ไม่เปลี่ยน my_set จากด้านบน


10

ตามที่ระบุไว้โดยคำตอบอื่น ๆ อีกมากมายlist.remove()จะทำงาน แต่โยนValueErrorถ้ารายการไม่ได้อยู่ในรายการ ด้วย python 3.4+ มีวิธีการจัดการเรื่องนี้ที่น่าสนใจโดยใช้ตัวจัดการบริบท :

from contextlib import suppress
with suppress(ValueError):
    a.remove('b')

8

การค้นหาค่าในรายการแล้วลบดัชนีนั้น (ถ้ามี) ทำได้ง่ายขึ้นเพียงแค่ใช้วิธีการลบรายการ:

>>> a = [1, 2, 3, 4]
>>> try:
...   a.remove(6)
... except ValueError:
...   pass
... 
>>> print a
[1, 2, 3, 4]
>>> try:
...   a.remove(3)
... except ValueError:
...   pass
... 
>>> print a
[1, 2, 4]

หากคุณทำสิ่งนี้บ่อยครั้งคุณสามารถสรุปได้ในฟังก์ชั่น:

def remove_if_exists(L, value):
  try:
    L.remove(value)
  except ValueError:
    pass

8

ตัวอย่างนี้เร็วและจะลบค่าทั้งหมดจากรายการ:

a = [1,2,3,1,2,3,4]
while True:
    try:
        a.remove(3)
    except:
        break
print a
>>> [1, 2, 1, 2, 4]

2
ถ้าคุณทำเช่นนี้คุณควรจริงๆเท่านั้นบนbreak except ValueError
Anthon

8

ในหนึ่งบรรทัด:

a.remove('b') if 'b' in a else None

บางครั้งมันก็มีประโยชน์

ง่ายยิ่งขึ้น:

if 'b' in a: a.remove('b')

7

หากองค์ประกอบของคุณแตกต่างจากนั้นความแตกต่างง่ายๆจะทำ

c = [1,2,3,4,'x',8,6,7,'x',9,'x']
z = list(set(c) - set(['x']))
print z
[1, 2, 3, 4, 6, 7, 8, 9]

2
หากองค์ประกอบของคุณมีความแตกต่างและคุณไม่สนใจเกี่ยวกับการสั่งซื้อ
Tom Zych


2

เขียนทับรายการโดยการทำดัชนีทุกอย่างยกเว้นองค์ประกอบที่คุณต้องการลบ

>>> s = [5,4,3,2,1]
>>> s[0:2] + s[3:]
[5, 4, 2, 1]

2

ด้วยห่วงสำหรับและเงื่อนไข:

def cleaner(seq, value):    
    temp = []                      
    for number in seq:
        if number != value:
            temp.append(number)
    return temp

และถ้าคุณต้องการลบบางส่วน แต่ไม่ใช่ทั้งหมด:

def cleaner(seq, value, occ):
    temp = []
    for number in seq:
        if number == value and occ:
            occ -= 1
            continue
        else:
            temp.append(number)
    return temp


1

ยกตัวอย่างเช่นเราต้องการลบ 1 ทั้งหมดออกจาก x นี่คือวิธีที่ฉันจะไปเกี่ยวกับมัน:

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

ตอนนี้เป็นการใช้งานจริงของวิธีการของฉัน:

def Function(List, Unwanted):
    [List.remove(Unwanted) for Item in range(List.count(Unwanted))]
    return List
x = Function(x, 1)
print(x)

และนี่คือวิธีการของฉันในบรรทัดเดียว:

[x.remove(1) for Item in range(x.count(1))]
print(x)

ทั้งคู่ให้สิ่งนี้เป็นเอาต์พุต:

[2, 3, 2, 3, 2, 3]

หวังว่านี่จะช่วยได้ ป.ล. โปรดทราบว่านี่เป็นเวอร์ชั่น 3.6.2 ดังนั้นคุณอาจจำเป็นต้องปรับเปลี่ยนให้เป็นเวอร์ชั่นเก่ากว่า


1

บางทีโซลูชันของคุณอาจใช้งานได้กับ ints แต่มันใช้ไม่ได้กับพจนานุกรม

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

ในทางกลับกัน 'del' ก็ทำงานได้ไม่ถูกต้องเช่นกัน ในกรณีของฉันการใช้ python 3.6: เมื่อฉันพยายามลบองค์ประกอบจากรายการในคำสั่ง 'for' ด้วย 'del' ด้วย python หลามเปลี่ยนดัชนีในกระบวนการและ bucle หยุดก่อนเวลาอันควร ใช้งานได้เฉพาะเมื่อคุณลบองค์ประกอบตามองค์ประกอบในลำดับที่กลับรายการ ด้วยวิธีนี้คุณไม่ต้องเปลี่ยนดัชนีอาร์เรย์องค์ประกอบที่ค้างอยู่เมื่อคุณทำมัน

จากนั้นฉันใช้:

c = len(list)-1
for element in (reversed(list)):
    if condition(element):
        del list[c]
    c -= 1
print(list)

โดยที่ 'list' เป็นเหมือน [{'key1': value1 '}, {' key2 ': value2}, {' key3 ': value3}, ... ]

นอกจากนี้คุณสามารถทำ pythonic เพิ่มเติมโดยใช้ enumerate:

for i, element in enumerate(reversed(list)):
    if condition(element):
        del list[(i+1)*-1]
print(list)

0
arr = [1, 1, 3, 4, 5, 2, 4, 3]

# to remove first occurence of that element, suppose 3 in this example
arr.remove(3)

# to remove all occurences of that element, again suppose 3
# use something called list comprehension
new_arr = [element for element in arr if element!=3]

# if you want to delete a position use "pop" function, suppose 
# position 4 
# the pop function also returns a value
removed_element = arr.pop(4)

# u can also use "del" to delete a position
del arr[4]

0

สิ่งนี้จะลบอินสแตนซ์ทั้งหมดของ"-v"อาร์เรย์sys.argvและไม่บ่นหากไม่พบอินสแตนซ์:

while "-v" in sys.argv:
    sys.argv.remove('-v')

คุณสามารถดูรหัสในการดำเนินการในไฟล์ที่เรียกว่าspeechToText.py:

$ python speechToText.py -v
['speechToText.py']

$ python speechToText.py -x
['speechToText.py', '-x']

$ python speechToText.py -v -v
['speechToText.py']

$ python speechToText.py -v -v -x
['speechToText.py', '-x']

-1

นี้คือคำตอบของฉันเพียงแค่ใช้ในขณะที่และสำหรับ

def remove_all(data, value):
    i = j = 0
    while j < len(data):
        if data[j] == value:
            j += 1
            continue
        data[i] = data[j]
        i += 1
        j += 1
    for x in range(j - i):
        data.pop()
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.