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.