Kiểm tra xem một mục danh sách Python có chứa một chuỗi bên trong một chuỗi khác không


588

Tôi có một danh sách:

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

và muốn tìm kiếm các mục có chứa chuỗi 'abc'. Làm thế nào tôi có thể làm điều đó?

if 'abc' in my_list:

sẽ kiểm tra nếu 'abc'tồn tại trong danh sách, nhưng nó là một phần của 'abc-123''abc-456', 'abc'không tồn tại trên riêng của mình. Vì vậy, làm thế nào tôi có thể nhận được tất cả các mặt hàng có chứa 'abc'?


19
Để kiểm tra ngược lại (nếu một chuỗi chứa một trong số nhiều chuỗi): stackoverflow.com/a/6531704/2436175
Antonio

Nếu các phần bên trái của các mục là duy nhất, hãy xem xét việc xây dựng một lệnh từ danh sách: Tìm một mục trong danh sách dựa trên chuỗi một phần
Georgy

Câu trả lời:


931

Nếu bạn chỉ muốn kiểm tra sự hiện diện của abcbất kỳ chuỗi nào trong danh sách, bạn có thể thử

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

Nếu bạn thực sự muốn có được tất cả các mục có chứa abc, sử dụng

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

Tôi phải kiểm tra nếu một mục nằm trong một mảng gồm 6 phần tử. Là nhanh hơn để làm 6 "nếu" hoặc là như vậy?
Olivier Pons

42
@OlivierPons, chỉ cần làmif myitem in myarray:
alldayremix

8
Một cách khác để có được tất cả các chuỗi chứa chuỗi con 'abc':filter(lambda element: 'abc' in element, some_list)
driftcatcher

2
@ p014k: sử dụng index()phương thức:try: return mylist.index(myitem); except ValueError: pass
Sven Marnach

1
@midkin: Tôi không hiểu chính xác những gì bạn đã cố gắng làm, cũng như làm thế nào nó đi sai. Bạn có thể sẽ gặp nhiều may mắn hơn bằng cách hỏi một câu hỏi mới (với nút "Hỏi câu hỏi"), sao chép mã chính xác của bạn, những gì bạn sẽ mong đợi mã sẽ làm và những gì nó thực sự đã làm. "Không hoạt động" là hoàn toàn vô nghĩa trừ khi bạn xác định "hoạt động" nghĩa là gì trong bối cảnh này, nhưng ngay cả khi đó tốt hơn là giải thích những gì thực sự xảy ra thay vì nói những gì không.
Sven Marnach 16/2/2015

104

Chỉ cần ném này ngoài kia: nếu bạn tình cờ cần phải phù hợp với nhiều hơn một chuỗi, ví dụ abcdef, bạn có thể kết hợp hai comprehensions như sau:

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

Đầu ra:

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

4
Đây chính xác là những gì tôi đã googling cho .. Cảm ơn!
N8TRO

2
Bạn cũng có thể sử dụng {s for s in my_list for xs in matchers if xs in s}(lưu ý dấu ngoặc nhọn để tạo một bộ duy nhất). Có thể dễ đọc hơn, nhưng có thể chậm hơn nếu hầu hết scác giá trị sẽ có một trận đấu, vì ý chí của bạn anysẽ dừng lại một cách hiệu quả ở trận đấu đầu tiên.
Matthias Fripp

82

Sử dụng filterđể có được tại các yếu tố có abc.

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

Bạn cũng có thể sử dụng một danh sách hiểu.

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

Nhân tiện, không sử dụng từ này listlàm tên biến vì nó đã được sử dụng cho listloại.


50

Nếu bạn chỉ cần biết liệu 'abc' có nằm trong một trong các mục hay không thì đây là cách ngắn nhất:

if 'abc' in str(my_list):

1
Điều này sẽ thất bại nếu bạn có một danh sách ["abc1", "1abc2"] vì nó sẽ tìm thấy kết quả khớp vì chuỗi 'abc' sẽ nằm trong chuỗi mới được tạo
csseller

2
Đúng, đây là hành vi dự định ... đúng nếu bất kỳ mục nào có chứa 'abc'
RogerS

7
Tôi không biết tại sao tất cả những người khác quyết định thực hiện những giải pháp lambda phức tạp đó khi họ không cần! Làm tốt lắm @RogerS
ntk4

1
Trên thực tế, cùng một câu hỏi gần như tự trả lời ... Tôi chỉ thêm 3 chữ cái vào đó.
RogerS

1
Đó là một giải pháp tốt, nhưng nếu bạn muốn tìm các mục có chứa chuỗi đã cho, bạn sẽ không thành công. Tại đây bạn tìm hiểu xem có bất kỳ mục nào chứa chuỗi không.
cslotty

18

Đây là một câu hỏi khá cũ, nhưng tôi đưa ra câu trả lời này vì các câu trả lời trước không đối phó với các mục trong danh sách không phải là chuỗi (hoặc một loại đối tượng lặp lại). Các mục như vậy sẽ làm cho toàn bộ danh sách hiểu không thành công với một ngoại lệ.

Để xử lý một cách duyên dáng với các mục như vậy trong danh sách bằng cách bỏ qua các mục không thể lặp lại, hãy sử dụng như sau:

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

sau đó, với một danh sách như vậy:

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

bạn vẫn sẽ nhận được các mục phù hợp (['abc-123', 'abc-456'] )

Các thử nghiệm cho iterable có thể không phải là tốt nhất. Có được từ đây: Trong Python, làm cách nào để xác định xem một đối tượng có thể lặp lại không?


Sẽ không [el for el in lst if el and (st in el)]có ý nghĩa hơn trong ví dụ đã cho?
Gordo

@tinix Tôi không xử lý các đối tượng không thể lặp lại một cách duyên dáng, phải không?
Robert Muil

"Ví dụ đưa ra" my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456'] không cần quá phức tạp hóa nó.
Gordo

1
Có hoàn toàn - câu trả lời được chấp nhận là hoàn toàn phù hợp và đề xuất của tôi phức tạp hơn, vì vậy hãy bỏ qua nó - Tôi chỉ đưa ra trong trường hợp ai đó có cùng một vấn đề như tôi có: các mục không thể lặp lại trong danh sách đó là khả năng trong thế giới thực mặc dù không tồn tại trong ví dụ đã cho.
Robert Muil

13
x = 'aaa'
L = ['aaa-12', 'bbbaaa', 'cccaa']
res = [y for y in L if x in y]

10
for item in my_list:
    if item.find("abc") != -1:
        print item

3
Nếu bạn định thực hiện phương pháp này, tôi nghĩ sẽ tốt hơn khi if 'abc' in itemsử dụng item.find('abc') == -1.
Wyatt Baldwin


4

Sử dụng __contains__()phương thức của lớp chuỗi Pythons.:

a = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
for i in a:
    if i.__contains__("abc") :
        print(i, " is containing")

3

Tôi chưa quen với Python. Tôi đã nhận được mã dưới đây làm việc và làm cho nó dễ hiểu:

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

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

for item in my_list:
    if (item.find('abc')) != -1:
        print ('Found at ', item)

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

pattern=re.compile(r'abc') 

pattern.findall(mylist)

Trong Python3.6, điều này đưa ra một lỗi: TypeError: chuỗi dự kiến ​​hoặc đối tượng giống byte
AimForClarity

1
@AimForClarity Có. re.findall trong python3.6 mong đợi một chuỗi. Một sự thay thế sẽ là bằng cách chuyển đổi danh sách thành một chuỗi 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
Xin lỗi vì định dạng kém. Không thể làm ngắt dòng thích hợp vì một số lý do.
arun_munagala

0

Tôi đã thực hiện một tìm kiếm, yêu cầu bạn nhập một giá trị nhất định, sau đó nó sẽ tìm kiếm một giá trị từ danh sách chứa đầu vào của bạn:

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)

Hãy thử tìm kiếm 'abc'.


0
def find_dog(new_ls):
    splt = new_ls.split()
    if 'dog' in splt:
        print("True")
    else:
        print('False')


find_dog("Is there a dog here?")

0

Tôi cần các chỉ số danh sách tương ứng với một trận đấu như sau:

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

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

đầu ra

[0, 3]

-1

Câu hỏi: Cung cấp thông tin của 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

Từ hiểu biết của tôi, một tuyên bố 'cho' sẽ luôn tiêu tốn thời gian.

Khi chiều dài danh sách tăng lên, thời gian thực hiện cũng sẽ tăng lên.

Tôi nghĩ rằng, tìm kiếm một chuỗi con trong một chuỗi với câu lệnh 'is' nhanh hơn một chút.

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

Nhưng, tôi đồng ý rằng anytuyên bố này dễ đọc hơn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.