Periksa apakah item daftar Python berisi string di dalam string lain


588

Saya punya daftar:

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

dan ingin mencari item yang berisi string 'abc'. Bagaimana saya bisa melakukan itu?

if 'abc' in my_list:

akan memeriksa jika 'abc'ada dalam daftar tetapi itu adalah bagian dari 'abc-123'dan 'abc-456', 'abc'tidak ada dengan sendirinya. Jadi bagaimana saya bisa mendapatkan semua barang yang mengandung 'abc'?


19
Untuk memeriksa yang sebaliknya (jika satu string berisi satu di antara banyak string): stackoverflow.com/a/6531704/2436175
Antonio

Jika bagian kiri dari entri adalah unik, pertimbangkan untuk membuat dict dari daftar: Temukan entri dalam daftar berdasarkan string parsial
Georgy

Jawaban:


931

Jika Anda hanya ingin memeriksa keberadaan abcstring apa pun dalam daftar, Anda bisa mencoba

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

Jika Anda benar-benar ingin mendapatkan semua item yang mengandung abc, gunakan

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

Saya harus memeriksa apakah satu item dalam array 6 elemen. Apakah lebih cepat melakukan 6 "jika" atau sama?
Olivier Pons

42
@OlivierPons, lakukan sajaif myitem in myarray:
alldayremix

8
Cara lain untuk mendapatkan semua string yang mengandung substring 'abc':filter(lambda element: 'abc' in element, some_list)
driftcatcher

2
@ p014k: gunakan index()metode:try: return mylist.index(myitem); except ValueError: pass
Sven Marnach

1
@ idkin: Saya tidak mengerti apa yang sebenarnya Anda coba lakukan, atau bagaimana kesalahannya. Anda mungkin akan lebih beruntung dengan mengajukan pertanyaan baru (dengan tombol "Ajukan Pertanyaan"), menyalin kode persis Anda, apa yang Anda harapkan dilakukan oleh kode, dan apa yang sebenarnya dilakukan. "Tidak berhasil" sama sekali tidak ada artinya kecuali Anda mendefinisikan apa yang dimaksud "bekerja" dalam konteks ini, tetapi bahkan lebih baik untuk menjelaskan apa yang sebenarnya terjadi daripada mengatakan apa yang tidak.
Sven Marnach

104

Hanya membuang ini di luar sana: jika Anda perlu mencocokkan dengan lebih dari satu string, misalnya abcdan def, Anda dapat menggabungkan dua pemahaman sebagai berikut:

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

Keluaran:

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

4
Ini persis seperti apa yang saya cari di Google .. Terima kasih!
N8TRO

2
Anda juga bisa menggunakan {s for s in my_list for xs in matchers if xs in s}(perhatikan tanda kurung keriting untuk membuat set yang unik). Mungkin lebih mudah dibaca, tetapi bisa lebih lambat jika sebagian besar snilai memiliki kecocokan, karena Anda anyakan efisien berhenti pada kecocokan pertama.
Matthias Fripp

82

Gunakan filteruntuk mendapatkan elemen-elemen yang ada abc.

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

Anda juga dapat menggunakan pemahaman daftar.

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

Omong-omong, jangan gunakan kata itu listsebagai nama variabel karena sudah digunakan untuk listjenisnya.


50

Jika Anda hanya perlu tahu apakah 'abc' ada di salah satu item, ini adalah cara terpendek:

if 'abc' in str(my_list):

1
Ini akan gagal jika Anda memiliki daftar ["abc1", "1abc2"] karena akan menemukan kecocokan karena string 'abc' akan berada di string yang baru dibuat
cgseller

2
Ya, ini adalah perilaku yang dimaksudkan ... benar jika salah satu item berisi 'abc'
RogerS

7
Saya tidak tahu mengapa semua orang ini memutuskan untuk melakukan solusi lambda yang berbelit-belit itu ketika mereka tidak perlu melakukannya! Kerja bagus @RogerS
ntk4

1
Sebenarnya pertanyaan yang sama hampir menjawab sendiri ... Saya baru saja menambahkan 3 huruf padanya.
RogerS

1
Ini solusi yang bagus, tetapi jika Anda ingin menemukan item yang berisi string yang diberikan, Anda tidak akan berhasil. Di sini Anda mencari tahu apakah ada item yang berisi string.
cslotty

18

Ini pertanyaan yang cukup lama, tetapi saya menawarkan jawaban ini karena jawaban sebelumnya tidak mengatasi item dalam daftar yang bukan string (atau semacam objek yang dapat diubah). Barang-barang seperti itu akan menyebabkan seluruh pemahaman daftar gagal dengan pengecualian.

Untuk menangani item-item semacam itu dalam daftar dengan melewatkan item-item yang tidak dapat diubah, gunakan yang berikut ini:

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

kemudian, dengan daftar seperti itu:

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

Anda masih akan mendapatkan item yang cocok ( ['abc-123', 'abc-456'])

Tes untuk iterable mungkin bukan yang terbaik. Mendapatnya dari sini: Dengan Python, bagaimana cara menentukan apakah suatu objek dapat diubah?


Bukankah [el for el in lst if el and (st in el)]lebih masuk akal dalam contoh yang diberikan?
Gordo

@ tinix Saya tidak akan menangani objek yang tidak dapat diubah dengan anggun, bukan?
Robert Muil

"diberikan contoh" my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456'] tidak perlu terlalu rumit.
Gordo

1
Ya benar - jawaban yang diterima sangat cocok dan saran saya lebih rumit, jadi silakan abaikan saja - Saya baru saja menawarkan jika seseorang memiliki masalah yang sama dengan saya: item yang tidak dapat diubah dalam daftar tersebut adalah kemungkinan di dunia nyata meskipun tidak ada dalam contoh yang diberikan.
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
Jika Anda akan mengambil pendekatan ini, saya pikir lebih idiomatis untuk dilakukan if 'abc' in itemdaripada menggunakan item.find('abc') == -1.
Wyatt Baldwin


4

Gunakan __contains__()metode kelas string Pythons .:

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

3

Saya baru mengenal Python. Saya mendapatkan kode di bawah ini yang berfungsi dan membuatnya mudah dimengerti:

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)

Dalam Python3.6 ini memberikan kesalahan: TypeError: string yang diharapkan atau objek seperti byte
AimForClarity

1
@AimForClarity Ya. re.findall di python3.6 mengharapkan sebuah string. Alternatifnya adalah dengan mengubah daftar menjadi string 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
Maaf untuk pemformatan yang buruk. Tidak dapat melakukan jeda baris yang tepat karena alasan tertentu.
arun_munagala

0

Saya melakukan pencarian, yang mengharuskan Anda untuk memasukkan nilai tertentu, maka itu akan mencari nilai dari daftar yang berisi masukan Anda:

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)

Coba cari '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

Saya membutuhkan daftar indeks yang sesuai dengan pertandingan sebagai berikut:

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

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

keluaran

[0, 3]

-1

Pertanyaan: Berikan informasi 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

Dari pengetahuan saya, pernyataan 'untuk' akan selalu menghabiskan waktu.

Ketika panjang daftar bertambah, waktu eksekusi juga akan bertambah.

Saya pikir, mencari substring dalam string dengan pernyataan 'is' sedikit lebih cepat.

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

Tapi, saya setuju bahwa anypernyataan itu lebih mudah dibaca.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.