ตรวจสอบว่ารายการ Python มีสตริงอยู่ภายในสตริงอื่นหรือไม่


587

ฉันมีรายการ:

my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']

'abc'และต้องการที่จะค้นหารายการที่มีสตริง ฉันจะทำสิ่งนั้นได้อย่างไร

if 'abc' in my_list:

จะตรวจสอบว่า'abc'มีอยู่ในรายการ แต่มันเป็นส่วนหนึ่งของ'abc-123'และ'abc-456', 'abc'ไม่ได้อยู่ในตัวเอง ดังนั้นฉันจะได้รับรายการทั้งหมดที่มี'abc'?


19
ในการตรวจสอบสิ่งที่ตรงกันข้าม (หากมีหนึ่งสตริงมีหนึ่งในหลาย ๆ สตริง): stackoverflow.com/a/6531704/2436175
Antonio

หากส่วนด้านซ้ายของรายการไม่ซ้ำกันให้พิจารณาการสร้าง dict จากรายการ: ค้นหารายการในรายการตามสตริงบางส่วน
Georgy

คำตอบ:


930

หากคุณต้องการตรวจสอบว่ามีabcสตริงในรายการใดบ้างคุณสามารถลอง

some_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
if any("abc" in s for s in some_list):
    # whatever

หากคุณต้องการรับสิ่งของทั้งหมดที่มีอยู่abcให้ใช้

matching = [s for s in some_list if "abc" in s]

ฉันต้องตรวจสอบว่ารายการหนึ่งอยู่ในอาร์เรย์ของ 6 องค์ประกอบ มันเร็วกว่าที่จะทำ 6 "ถ้า" หรือมันเหมือนกันหรือไม่?
Olivier Pons

42
@OlivierPons เพียงทำif myitem in myarray:
alldayremix

8
อีกวิธีหนึ่งในการรับสตริงทั้งหมดที่มีสตริงย่อย 'abc':filter(lambda element: 'abc' in element, some_list)
driftcatcher

2
@ p014k: ใช้index()วิธีการ:try: return mylist.index(myitem); except ValueError: pass
Sven Marnach

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

104

เพียงการขว้างปาออกนี้มี: ถ้าคุณเกิดขึ้นเพื่อให้ตรงกับความต้องการกับสตริงมากกว่าหนึ่งตัวอย่างabcและdefคุณสามารถรวมสอง comprehensions ดังนี้

matchers = ['abc','def']
matching = [s for s in my_list if any(xs in s for xs in matchers)]

เอาท์พุท:

['abc-123', 'def-456', 'abc-456']

4
นี่คือสิ่งที่ฉันกำลังทำเพื่อ .. ขอบคุณ!
N8TRO

2
คุณสามารถใช้{s for s in my_list for xs in matchers if xs in s}(สังเกตเครื่องหมายวงเล็บปีกกาเพื่อสร้างชุดที่ไม่ซ้ำกัน) อาจจะอ่านง่ายขึ้น แต่อาจช้าลงหากsค่าส่วนใหญ่จะมีการแข่งขันเนื่องจากคุณanyจะหยุดอย่างมีประสิทธิภาพในการแข่งขันครั้งแรก
Matthias Fripp

82

ใช้เพื่อให้ได้องค์ประกอบที่มีfilterabc

>>> lst = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
>>> print filter(lambda x: 'abc' in x, lst)
['abc-123', 'abc-456']

คุณยังสามารถใช้ list comprehension

>>> [x for x in lst if 'abc' in x]

อย่างไรก็ตามอย่าใช้คำlistว่าชื่อตัวแปรเนื่องจากมันถูกใช้สำหรับlistประเภทนี้แล้ว


50

หากคุณเพียงแค่ต้องรู้ว่า 'abc' อยู่ในรายการใดรายการหนึ่งนี่เป็นวิธีที่สั้นที่สุด:

if 'abc' in str(my_list):

1
สิ่งนี้จะล้มเหลวหากคุณมีรายการ ["abc1", "1abc2"] เนื่องจากจะพบการแข่งขันเนื่องจากสตริง 'abc' จะอยู่ในสตริงที่สร้างขึ้นใหม่
cgseller

2
ใช่นี่เป็นพฤติกรรมที่ตั้งใจ ... จริงถ้ามีรายการใด ๆ ที่มี 'abc'
RogerS

7
ฉันไม่รู้ว่าทำไมคนอื่น ๆ เหล่านี้ตัดสินใจทำแลมบ์ดาโซลูชั่นที่ซับซ้อนเมื่อพวกเขาไม่ต้องการ! Nice job @RogerS
ntk4

1
ที่จริงคำถามเดียวกันเกือบตอบตัวเอง ... ฉันเพิ่งเพิ่ม 3 ตัวอักษรไป
RogerS

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

18

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

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

[el for el in lst if isinstance(el, collections.Iterable) and (st in el)]

จากนั้นด้วยรายการดังกล่าว:

lst = [None, 'abc-123', 'def-456', 'ghi-789', 'abc-456', 123]
st = 'abc'

คุณจะยังคงได้รับรายการที่ตรงกัน ( ['abc-123', 'abc-456'])

การทดสอบซ้ำได้อาจไม่ดีที่สุด รับได้จากที่นี่: ใน Python ฉันจะทราบได้อย่างไรว่าวัตถุนั้นสามารถทำซ้ำได้?


จะไม่มี[el for el in lst if el and (st in el)]เหตุผลเพิ่มเติมในตัวอย่างที่ให้มาใช่ไหม
Gordo

@tinix ฉันไม่ได้จัดการกับวัตถุที่ไม่สามารถทำซ้ำได้อย่างสง่างามใช่มั้ย
Robert Muil

"ตัวอย่างที่กำหนด" my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456'] ไม่จำเป็นต้องซับซ้อนเกินความจำเป็น
Gordo

1
ใช่อย่างแน่นอน - คำตอบที่ได้รับการยอมรับเหมาะสมอย่างสมบูรณ์และข้อเสนอแนะของฉันมีความซับซ้อนมากขึ้นดังนั้นอย่าลังเลที่จะเสนอ - ฉันเพิ่งเสนอในกรณีที่บางคนมีปัญหาเช่นเดียวกับที่ฉันมี: รายการที่ไม่ซ้ำ แม้จะไม่ได้มีอยู่ในตัวอย่างที่กำหนด
Robert Muil





3

ฉันยังใหม่กับ Python ฉันได้รับรหัสด้านล่างทำงานและทำให้เข้าใจง่าย:

my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
for str in my_list:
    if 'abc' in str:
       print(str)


0
mylist=['abc','def','ghi','abc']

pattern=re.compile(r'abc') 

pattern.findall(mylist)

ใน Python3.6 สิ่งนี้จะทำให้เกิดข้อผิดพลาด: TypeError: คาดว่าสตริงหรือวัตถุที่คล้ายไบต์
AimForClarity

1
@AmForClarity ใช่ re.findall ใน python3.6 ต้องการสตริง อีกทางเลือกหนึ่งคือการแปลงรายการเป็นสตริง import re mylist=['abc','def','ghi','abcff'] my_list_string=''.join(mylist) string_to_find="abc" res=re.findall(string_to_find,my_list_string) print(res)
arun_munagala

1
ขออภัยสำหรับรูปแบบที่ไม่ดี ไม่สามารถทำการแบ่งบรรทัดที่เหมาะสมด้วยเหตุผลบางอย่าง
arun_munagala

0

ฉันทำการค้นหาซึ่งคุณต้องป้อนค่าบางค่าจากนั้นจะค้นหาค่าจากรายการที่มีการป้อนข้อมูลของคุณ:

my_list = ['abc-123',
        'def-456',
        'ghi-789',
        'abc-456'
        ]

imp = raw_input('Search item: ')

for items in my_list:
    val = items
    if any(imp in val for items in my_list):
        print(items)

ลองค้นหา 'abc'



0

ฉันต้องการดัชนีรายการที่สอดคล้องกับการแข่งขันดังนี้:

lst=['abc-123', 'def-456', 'ghi-789', 'abc-456']

[n for n, x in enumerate(lst) if 'abc' in x]

เอาท์พุต

[0, 3]

-1

คำถาม: ให้ข้อมูลของ abc

    a = ['abc-123', 'def-456', 'ghi-789', 'abc-456']


    aa = [ string for string in a if  "abc" in string]
    print(aa)

Output =>  ['abc-123', 'abc-456']

-2

จากความรู้ของฉันคำสั่ง 'สำหรับ' จะใช้เวลาเสมอ

เมื่อความยาวของรายการโตขึ้นเวลาดำเนินการก็จะเพิ่มขึ้นเช่นกัน

ฉันคิดว่าการค้นหาสตริงย่อยในสตริงด้วยคำสั่ง 'is' นั้นเร็วกว่าเล็กน้อย

In [1]: t = ["abc_%s" % number for number in range(10000)]

In [2]: %timeit any("9999" in string for string in t)
1000 loops, best of 3: 420 µs per loop

In [3]: %timeit "9999" in ",".join(t)
10000 loops, best of 3: 103 µs per loop

แต่ฉันยอมรับว่าanyข้อความนั้นอ่านง่ายขึ้น

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