Başka bir dizede birden fazla dizenin olup olmadığını kontrol edin


378

Bir dizideki dizelerden herhangi birinin başka bir dizede olup olmadığını nasıl kontrol edebilirim?

Sevmek:

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"

Bu kod işe yaramıyor, sadece ne elde etmek istediğimi göstermek için.


5
Özellikle dize boyutu ve aramak için "iğne" sayısı ile karşılaştırıldığında, mükemmel olarak derlenmiş bir normal ifade ile karşılaştırıldığında (henüz) herhangi bir cevap yoktur şaşırdım.
— Pat

3
@Pat Şaşırmadım. Soru performansla ilgili değil. Bugün çoğu programcı bunu yapmak ve okunabilirlik için daha fazla önem veriyor. Performans sorusu geçerli, ancak farklı bir soru.
— guettli

13
Str'yi değişken olarak kullanmak kafa karıştırıcıdır ve ayrılmış bir sözcük olduğu için beklenmedik davranışlara neden olabilir; bağlantıya bakınız .
— Akıllı Adam

regex [abc]de mükemmel bir şekilde çalışır ve test edilecek birkaç adaydan fazlası varsa daha hızlı olacaktır. Ancak dizeler keyfi ise ve bir regex oluşturmak için bunları önceden bilmiyorsanız, any(x in str for x in a)yaklaşımı kullanmanız gerekir .
— smci

@CleverGuy Haklısınız, bu ayrılmış bir kelime olmasa da, aksi takdirde ona atayamazsınız. Bu bir yerleşik.
— wjandrea

Yanıtlar:


717

Şunları kullanabilirsiniz any:

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

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

Benzer şekilde listedeki tüm dizelerin bulunup bulunmadığını kontrol etmek için allyerine kullanın any.


11
any () bir yinelenebilir alır. Hangi Python sürümünü kullandığınızdan emin değilim, ancak 2.6'da [] argümanınızı any () öğesine koymanız gerekecek. any ([x in str in x in a]), böylece kavrama yinelenebilir bir değer döndürür. Ama belki Python'un sonraki sürümleri bunu zaten yapıyor.
— emispowder

7
@Mark Byers: Geç yorum için özür dilerim, ancak bulunan dizeyi yazdırmanın bir yolu var mı? Bunu nasıl yapardın. Teşekkür ederim.
— Shankar Kumar

3
Anladığımdan emin değilim, eğer a listeyse ve str eşleşecek şey ise, x nedir? Python acemi ftw. :)
— kırmızı

2
@red: for x in a"listedeki her öğe için" gibi okuyabilirsiniz . Yana adizeleri listesidir ve xbu listenin bir elementtir, xbir dize ( 'a', orijinal örnekteki 'b', 'c' biri) olan
— Kullanıcı

6
@emispowder Python 2.6.9'da olduğu gibi benim için iyi çalışıyor.
— MPlanchard

67

any()İstediğiniz tek şeyse Trueya da Falseözellikle hangi dize / dizelerin eşleştiğini bilmek istiyorsanız, birkaç şey kullanabilirsiniz.

İlk eşleşmeyi istiyorsanız ( Falsevarsayılan olarak):

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

Tüm eşleşmeleri almak istiyorsanız (kopyalar dahil):

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

Yinelenmeyen tüm eşleşmeleri almak istiyorsanız (siparişi göz ardı ederek):

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

Yinelenmeyen tüm eşleşmeleri doğru sırada almak istiyorsanız:

matches = []
for x in a:
    if x in str and x not in matches:
        matches.append(x)

Lütfen son maç için örnek ekleyin
— Oleg Kokorin

@OlegKokorin: Eşleşen dizeleri buldukları sırayla bir liste oluşturur, ancak ikisi aynıysa yalnızca ilk dizeyi tutar.
— zondo

An kullanmak OrderedDictmuhtemelen bir listeden daha performanslıdır. "Listelerdeki kopyaların kaldırılması"
— wjandrea

44

Dizeler içeri girerse aveya struzarsa dikkatli olmalısınız . Basit çözümler O (S * (A ^ 2)) alır, burada Suzunluğu strve A, içindeki tüm dizelerin uzunluklarının toplamıdır a. Daha hızlı bir çözüm için, doğrusal zaman O (S + A) ile çalışan dize eşleşmesi için Aho-Corasick algoritmasına bakın.


Aho-Corasick önek yerine alt dizeleri de bulabilir mi?
— RetroCode

1
Bazı python Aho-Corasick kütüphaneleri burada ve burada
— vorpal

23

Sadece çeşitlilik eklemek için regex:

import re

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

veya listeniz çok uzunsa - any(re.findall(r'|'.join(a), str, re.IGNORECASE))


1
Bu, sorunun verilen kullanım durumu için geçerlidir. Eğer arama yaparsanız (veya *bu başarısız olursa, normal ifade sözdizimi için tırnak yapılması gerekir.
— guettli

2
Gerekirse kaçabilirsiniz '|'.join(map(re.escape, strings_to_match)). Muhtemelen sen re.compile('|'.join(...))de öyle.
— Artyer

12

A öğelerini yinelemeniz gerekir.

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"

2
Evet bunu nasıl yapacağımı biliyordum ama Marks cevap ile karşılaştırıldığında, bu korkunç bir kod.
— jahmax

10
Sadece Mark'ın kodunu anlarsan. Karşılaştığınız sorun dizinizin öğelerini incelememeniz. Kodunuzda yanlış olan şeyin özünü gizleyecek olan, istediğiniz şeyi başarmak için çok sayıda kısa, pythonic yol vardır.
— Seamus Campbell

9
'Korkunç kod' olabilir ama any () tam olarak bunu yapar . Ayrıca, bu size eşleşen gerçek dizeyi verirken, any () size bir eşleşme olduğunu söyler.
— alldayremix

4

jbernadas, karmaşıklığı azaltmak için Aho-Corasick-Algoritmasından bahsetmişti .

Python'da kullanmanın bir yolu:

  1. Aho_corasick.py'yi buradan indirin

  2. Ana Python dosyanızla aynı dizine koyun ve adlandırın aho_corasick.py

  3. Alroritmayı aşağıdaki kodla deneyin:

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

Aramanın büyük / küçük harfe duyarlı olduğunu unutmayın


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"

1

Bu gibi tek literal kontrol etmek istiyorsanız (herhangi bir tek kelime bir, e, .. vb w) varsayalım bağlamda bağlıdır içinde yeterli

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

original_word içindeki karakterlerden herhangi birini kontrol etmek istiyorsanız:

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

Eğer orijinal_word'de istediğiniz tüm girdileri istiyorsanız,

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")

Girdiğin ne olurdu? İki şeyi tanıyabilirim: bir şey aradığım cümle. Aradığım kelime dizisi. Ama siz üç değişkeni tanımlıyorsunuz ve üçüncü değişkenin ne olduğunu anlayamıyorum.
— '19

1

Dize'de tüm liste öğelerinin nasıl elde edileceği hakkında daha fazla bilgi

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

1

Şaşırtıcı derecede hızlı bir yaklaşım 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")

Bu a, herhangi bir çoklu karakter değeri içermiyorsa çalışır (bu durumda yukarıdaany listelenen şekilde kullanın ). Eğer öyleyse, bu belirtmek için basittir adize olarak: a = 'abc'.


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')

çıktı örnek resim


0

Hız için bu tür bir işlev kullanırsınız:

def check_string(string, substring_list):
    for substring in substring_list:
        if substring in string:
            return True
    return False

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)));
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.