Periksa apakah banyak string ada di string lain

378

Bagaimana saya bisa memeriksa jika ada string dalam array yang ada di string lain?

Suka:

a = ['a', 'b', 'c']
str = "a123"
if a in str:
  print "some of the strings found in str"
else:
  print "no strings found in str"

Kode itu tidak berfungsi, hanya untuk menunjukkan apa yang ingin saya capai.

Jahmax
sumber
5
Saya terkejut tidak ada (belum) jawaban dibandingkan dengan regex yang dikompilasi dalam hal perf, terutama dibandingkan dengan ukuran string dan jumlah "jarum" untuk mencari.
Pat
3
@Pat saya tidak terkejut. Pertanyaannya bukan tentang kinerja. Saat ini sebagian besar programmer lebih peduli untuk menyelesaikannya dan mudah dibaca. Pertanyaan kinerja valid, tetapi pertanyaan yang berbeda.
guettli
13
Menggunakan str sebagai variabel membingungkan dan dapat mengakibatkan perilaku yang tidak terduga karena merupakan kata yang dilindungi undang-undang; lihat tautan .
Si Pintar
regex [abc]juga bekerja dengan sangat baik dan akan lebih cepat jika ada lebih dari beberapa kandidat untuk diuji. Tetapi jika stringnya arbitrer dan Anda tidak mengetahuinya terlebih dahulu untuk membuat regex, Anda harus menggunakan any(x in str for x in a)pendekatan tersebut.
smci
@CleverGuy Anda benar, meskipun itu bukan kata yang dilindungi undang-undang, jika tidak, Anda tidak akan dapat menetapkannya. Itu builtin.
wjandrea

Jawaban:

717

Anda bisa menggunakan any:

a_string = "A string is more than its parts!"
matches = ["more", "wholesome", "milk"]

if any(x in a_string for x in matches):

Demikian pula untuk memeriksa apakah semua string dari daftar ditemukan, gunakan allbukan any.

Mark Byers
sumber
11
any () membutuhkan iterable. Saya tidak yakin versi Python mana yang Anda gunakan tetapi dalam 2.6 Anda harus meletakkan [] argumen Anda ke sembarang (). any ([x in str untuk x in a]) sehingga pemahaman mengembalikan sebuah iterable. Tapi mungkin versi Python nanti sudah melakukan ini.
emispowder
7
@ Markus Byers: Maaf atas komentar yang terlambat, tetapi apakah ada cara untuk mencetak string yang ditemukan? Bagaimana Anda melakukan ini? Terima kasih.
Shankar Kumar
3
Tidak yakin saya mengerti, jika a adalah daftar, dan str adalah hal yang cocok, apa x? Python newbie ftw. :)
red
2
@ red: Anda dapat membaca for x in aseperti "untuk setiap elemen dalam daftar". Karena aadalah daftar string, dan xmerupakan elemen dari daftar itu, xadalah string (salah satu dari 'a', 'b', 'c' dalam contoh asli)
Pengguna
6
@emispowder Ini bekerja dengan baik bagi saya apa adanya di Python 2.6.9.
MPlanchard
67

any()sejauh ini merupakan pendekatan terbaik jika semua yang Anda inginkan adalah Trueatau False, tetapi jika Anda ingin mengetahui secara spesifik string / string mana yang cocok, Anda dapat menggunakan beberapa hal.

Jika Anda ingin kecocokan pertama (dengan Falsesebagai default):

match = next((x for x in a if x in str), False)

Jika Anda ingin mendapatkan semua kecocokan (termasuk duplikat):

matches = [x for x in a if x in str]

Jika Anda ingin mendapatkan semua kecocokan non-duplikat (mengabaikan pesanan):

matches = {x for x in a if x in str}

Jika Anda ingin mendapatkan semua kecocokan non-duplikat dalam urutan yang benar:

matches = []
for x in a:
    if x in str and x not in matches:
        matches.append(x)
zondo
sumber
tolong tambahkan contoh untuk pertandingan terakhir juga
Oleg Kokorin
@ OlegKokorin: Ini membuat daftar string yang cocok dengan urutan yang sama dengan yang ditemukannya, tetapi hanya menyimpan yang pertama jika keduanya sama.
zondo
Menggunakan sebuah OrderedDictmungkin lebih banyak performan daripada daftar. Lihat jawaban ini pada "Menghapus duplikat dalam daftar"
wjandrea
44

Anda harus berhati-hati jika senar masuk aatau strsemakin panjang. Solusi langsung mengambil O (S * (A ^ 2)), di mana Spanjang strdan A adalah jumlah panjang semua string di a. Untuk solusi yang lebih cepat, lihat algoritma Aho-Corasick untuk pencocokan string, yang berjalan dalam waktu linear O (S + A).

Jupiter
sumber
dapatkah Aho-Corasick juga menemukan substring alih-alih awalan?
RetroCode
1
Beberapa perpustakaan python Aho-Corasick ada di sini dan di sini
vorpal
23

Untuk menambah keragaman dengan regex:

import re

if any(re.findall(r'a|b|c', str, re.IGNORECASE)):
    print 'possible matches thanks to regex'
else:
    print 'no matches'

atau jika daftar Anda terlalu panjang - any(re.findall(r'|'.join(a), str, re.IGNORECASE))

Shankar ARUL - jupyterdata.com
sumber
1
Ini berfungsi untuk kasus penggunaan yang diberikan dari pertanyaan. Jika Anda mencari (atau *ini gagal, karena mengutip untuk sintaks regex perlu dilakukan.
guettli
2
Anda dapat melarikan diri jika perlu dengan '|'.join(map(re.escape, strings_to_match)). Anda mungkin re.compile('|'.join(...))juga bisa.
Artyer
12

Anda perlu mengulangi elemen a.

a = ['a', 'b', 'c']
str = "a123"
found_a_string = False
for item in a:    
    if item in str:
        found_a_string = True

if found_a_string:
    print "found a match"
else:
    print "no match found"
Seamus Campbell
sumber
2
Ya saya tahu bagaimana melakukan itu tetapi dibandingkan dengan jawaban Marks, itu kode yang mengerikan.
jahmax
10
Hanya jika Anda mengerti kode Markus. Masalah yang Anda hadapi adalah Anda tidak memeriksa elemen array Anda. Ada banyak cara pythonic singkat untuk mencapai apa yang Anda inginkan yang akan menyembunyikan esensi dari apa yang salah dengan kode Anda.
Seamus Campbell
9
Mungkin 'kode mengerikan' tapi persis seperti apa () tidak . Juga, ini memberi Anda string aktual yang cocok, sedangkan any () hanya memberi tahu Anda ada kecocokan.
alldayremix
4

jbernadas sudah menyebutkan Aho-Corasick-Algorithm untuk mengurangi kompleksitas.

Berikut adalah salah satu cara untuk menggunakannya dalam Python:

  1. Unduh aho_corasick.py dari sini

  2. Letakkan di direktori yang sama dengan file Python utama Anda dan beri nama aho_corasick.py

  3. Coba aloritma dengan kode berikut:

    from aho_corasick import aho_corasick #(string, keywords)
    
    print(aho_corasick(string, ["keyword1", "keyword2"]))

Perhatikan bahwa pencarian peka huruf besar-kecil

Domi W
sumber
3
a = ['a', 'b', 'c']
str =  "a123"

a_match = [True for match in a if match in str]

if True in a_match:
  print "some of the strings found in str"
else:
  print "no strings found in str"
mluebke
sumber
1

Tergantung pada konteks anggaplah jika Anda ingin memeriksa satu literal seperti (kata tunggal a, e, w, .. dll) di sudah cukup

original_word ="hackerearcth"
for 'h' in original_word:
      print("YES")

jika Anda ingin memeriksa salah satu karakter di antara original_word: manfaatkan

if any(your_required in yourinput for your_required in original_word ):

jika Anda ingin semua input yang Anda inginkan dalam original_word itu, gunakan semua yang sederhana

original_word = ['h', 'a', 'c', 'k', 'e', 'r', 'e', 'a', 'r', 't', 'h']
yourinput = str(input()).lower()
if all(requested_word in yourinput for requested_word in original_word):
    print("yes")
Trinadh Koya
sumber
Apa yang akan menjadi masukan Anda? Saya dapat mengenali dua hal: kalimat di mana saya mencari sesuatu. Susunan kata yang saya cari. Tapi Anda menggambarkan tiga variabel dan saya tidak bisa mendapatkan apa yang ketiga.
1919
1

Hanya beberapa info lebih lanjut tentang cara mendapatkan semua elemen daftar yang tersedia di String

a = ['a', 'b', 'c']
str = "a123" 
list(filter(lambda x:  x in str, a))
Nilesh Birari
sumber
1

Pendekatan yang sangat cepat adalah menggunakan set:

a = ['a', 'b', 'c']
str = "a123"
if set(a) & set(str):
    print("some of the strings found in str")
else:
    print("no strings found in str")

Ini berfungsi jika atidak mengandung nilai multi-karakter (dalam hal ini digunakan anyseperti yang tercantum di atas ). Jika demikian, itu sederhana untuk menentukan asebagai string: a = 'abc'.

Berislav Lopac
sumber
0
flog = open('test.txt', 'r')
flogLines = flog.readlines()
strlist = ['SUCCESS', 'Done','SUCCESSFUL']
res = False
for line in flogLines:
     for fstr in strlist:
         if line.find(fstr) != -1:
            print('found') 
            res = True


if res:
    print('res true')
else: 
    print('res false')

contoh output gambar

LeftSpace
sumber
0

Saya akan menggunakan fungsi semacam ini untuk kecepatan:

def check_string(string, substring_list):
    for substring in substring_list:
        if substring in string:
            return True
    return False
Ivan Mikhailov
sumber
0
data = "firstName and favoriteFood"
mandatory_fields = ['firstName', 'lastName', 'age']


# for each
for field in mandatory_fields:
    if field not in data:
        print("Error, missing req field {0}".format(field));

# still fine, multiple if statements
if ('firstName' not in data or 
    'lastName' not in data or
    'age' not in data):
    print("Error, missing a req field");

# not very readable, list comprehension
missing_fields = [x for x in mandatory_fields if x not in data]
if (len(missing_fields)>0):
    print("Error, missing fields {0}".format(", ".join(missing_fields)));
Robert I
sumber