วิธีการลบสตริงย่อยเฉพาะจากชุดของสตริงใน Python?


160

ฉันมีชุดสตริงset1และสตริงทั้งหมดset1มีสตริงย่อยสองรายการที่ฉันไม่ต้องการและต้องการลบ
ตัวอย่างอินพุต: set1={'Apple.good','Orange.good','Pear.bad','Pear.good','Banana.bad','Potato.bad'}
โดยพื้นฐานแล้วฉันต้องการลบ.goodและ.badสตริงย่อยออกจากสตริงทั้งหมด
สิ่งที่ฉันพยายาม:

for x in set1:
    x.replace('.good','')
    x.replace('.bad','')

แต่นี่ดูเหมือนจะไม่ทำงานเลย ไม่มีการเปลี่ยนแปลงอย่างแน่นอนในเอาต์พุตและเหมือนกับอินพุต ฉันลองใช้for x in list(set1)แทนของเดิม แต่มันไม่เปลี่ยนแปลงอะไรเลย

คำตอบ:


187

เงื่อนไขไม่เปลี่ยนรูป string.replace(python 2.x) หรือstr.replace(python 3.x) สร้างสตริงใหม่ นี่คือที่ระบุไว้ในเอกสาร:

ส่งคืนสำเนาของสตริง s พร้อมกับสตริงย่อยเก่าที่เกิดขึ้นแทนที่ด้วยใหม่ทั้งหมด ...

ซึ่งหมายความว่าคุณต้องจัดสรรชุดอีกครั้งหรือเติมอีกครั้ง (การจัดสรรใหม่ง่ายขึ้นด้วยชุดความเข้าใจ) :

new_set = {x.replace('.good', '').replace('.bad', '') for x in set1}

3
string.replace()เลิกใช้แล้วใน python 3.x ตอนนี้เป็นstr.replace()
Yossarian42

71
>>> x = 'Pear.good'
>>> y = x.replace('.good','')
>>> y
'Pear'
>>> x
'Pear.good'

.replaceไม่เปลี่ยนสตริง แต่จะส่งคืนสำเนาของสตริงด้วยการแทนที่ คุณไม่สามารถเปลี่ยนสตริงได้โดยตรงเนื่องจากสตริงไม่เปลี่ยนรูป

คุณต้องนำค่าส่งคืนจากx.replaceและนำมาไว้ในชุดใหม่


แต่เมื่อฉันวนซ้ำชุดสตริงฉันจะอัปเดตชุดใหม่ได้อย่างไร ใช้ set_name.update? คุณแสดงให้เห็นหรือไม่?
controlfreak

12

สิ่งที่คุณต้องมีก็คือเวทย์มนตร์ดำ!

>>> a = ["cherry.bad","pear.good", "apple.good"]
>>> a = list(map(lambda x: x.replace('.good','').replace('.bad',''),a))
>>> a
['cherry', 'pear', 'apple']

5

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

import re
import string
set1={'Apple.good','Orange.good','Pear.bad','Pear.good','Banana.bad','Potato.bad'}

for x in set1:
    x.replace('.good',' ')
    x.replace('.bad',' ')
    x = re.sub('\.good$', '', x)
    x = re.sub('\.bad$', '', x)
    print(x)

2
บรรทัดx.replace('.good',' ')และx.replace('.bad',' ')ไม่ได้ทำอะไรกับผลลัพธ์สุดท้าย การพิมพ์จะเหมือนกันหากไม่มี
SrđanPopić

นอกจากนี้ฉันอยากจะมีเพียงหนึ่งบรรทัดด้วยre.subเช่นนี้:x = re.sub('((\.good$)|(\.bad$))', '', x)
SrđanPopić

@ SrđanPopićใช่ฉันเห็นด้วยกับคุณ
Vivek

เราควรแก้ไขให้ถูกต้องหรือไม่ (ลบreplaceและย้ายทุกอย่างไปยังre.subสายเดียว)
SrđanPopić

1
@ SrđanPopićฉันโพสต์คำตอบนี้เพราะมันง่ายและฉลาด
Vivek

3

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

>>> ind = ['p5','p1','p8','p4','p2','p8']
>>> newind = {x.replace('p','') for x in ind}
>>> newind
{'1', '2', '8', '5', '4'}

ฉันพิสูจน์ว่าใช้งานได้:

>>> ind = ['p5','p1','p8','p4','p2','p8']
>>> newind = [x.replace('p','') for x in ind]
>>> newind
['5', '1', '8', '4', '2', '8']

หรือ

>>> newind = []
>>> ind = ['p5','p1','p8','p4','p2','p8']
>>> for x in ind:
...     newind.append(x.replace('p',''))
>>> newind
['5', '1', '8', '4', '2', '8']

3

เมื่อมีสตริงย่อยหลายรายการที่จะลบตัวเลือกที่ง่ายและมีประสิทธิภาพตัวเลือกหนึ่งจะใช้re.subกับรูปแบบที่รวบรวมซึ่งเกี่ยวข้องกับการรวมเอาสตริงย่อยทั้งหมดเพื่อลบโดยใช้ไพพ์ regex OR ( |)

import re

to_remove = ['.good', '.bad']
strings = ['Apple.good','Orange.good','Pear.bad']

p = re.compile('|'.join(map(re.escape, to_remove))) # escape to handle metachars
[p.sub('', s) for s in strings]
# ['Apple', 'Orange', 'Pear']

1

หากรายการ

ฉันกำลังทำบางสิ่งบางอย่างสำหรับรายการซึ่งเป็นชุดของสตริงและคุณต้องการลบบรรทัดทั้งหมดที่มีซับสตริงที่แน่นอนคุณสามารถทำได้

import re
def RemoveInList(sub,LinSplitUnOr):
    indices = [i for i, x in enumerate(LinSplitUnOr) if re.search(sub, x)]
    A = [i for j, i in enumerate(LinSplitUnOr) if j not in indices]
    return A

ที่subเป็นลายที่คุณไม่ต้องการที่จะมีในรายการของเส้นLinSplitUnOr

ตัวอย่างเช่น

A=['Apple.good','Orange.good','Pear.bad','Pear.good','Banana.bad','Potato.bad']
sub = 'good'
A=RemoveInList(sub,A)

จากนั้นAจะเป็น

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


0

ถ้าคุณลบบางอย่างออกจากรายการคุณสามารถใช้วิธีนี้: (วิธีย่อยเป็นกรณี ๆ ไป)

new_list = []
old_list= ["ABCDEFG","HKLMNOP","QRSTUV"]

for data in old_list:
     new_list.append(re.sub("AB|M|TV", " ", data))

print(new_list) // output : [' CDEFG', 'HKL NOP', 'QRSTUV']
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.