Kiểm tra nếu nhiều chuỗi tồn tại trong một chuỗi khác


378

Làm cách nào để kiểm tra xem có bất kỳ chuỗi nào trong một mảng tồn tại trong một chuỗi khác không?

Giống:

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"

Mã đó không hoạt động, nó chỉ để hiển thị những gì tôi muốn đạt được.


5
Tôi ngạc nhiên không có (chưa) bất kỳ câu trả lời nào so với một biểu thức chính được biên dịch về độ hoàn hảo, đặc biệt là so với kích thước của chuỗi và số "kim" để tìm kiếm.
Pat

3
@Pat tôi không ngạc nhiên. Câu hỏi không phải là về hiệu suất. Ngày nay hầu hết các lập trình viên quan tâm nhiều hơn để hoàn thành nó và dễ đọc. Câu hỏi hiệu suất là hợp lệ, nhưng một câu hỏi khác.
guettli

13
Sử dụng str như một biến là khó hiểu và có thể dẫn đến hành vi không mong muốn vì đó là một từ dành riêng; xem liên kết .
chàng thông minh

regex [abc]cũng hoạt động hoàn hảo và sẽ nhanh hơn nếu có nhiều hơn một vài ứng cử viên để kiểm tra. Nhưng nếu các chuỗi là tùy ý và bạn không biết trước về chúng để xây dựng một biểu thức chính quy, bạn sẽ phải sử dụng any(x in str for x in a)cách tiếp cận.
smci

@CleverGuy Bạn nói đúng, mặc dù đó không phải là một từ dành riêng, nếu không bạn sẽ không thể gán cho nó. Đó là một nội dung.
wjandrea

Câu trả lời:


717

Bạn có thể sử dụng any:

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

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

Tương tự để kiểm tra nếu tất cả các chuỗi từ danh sách được tìm thấy, sử dụng allthay vì any.


11
bất kỳ () mất một lần lặp. Tôi không chắc bạn đang sử dụng phiên bản Python nào nhưng trong 2.6 bạn sẽ cần đặt [] xung quanh đối số của mình cho bất kỳ () nào. bất kỳ ([x in str cho x in a]) để sự hiểu biết trả về một lần lặp. Nhưng có lẽ các phiên bản sau của Python đã làm điều này.
hóa chất

7
@Mark Byers: Xin lỗi vì nhận xét muộn, nhưng có cách nào để in chuỗi đã được tìm thấy không? Bạn sẽ làm điều này như thế nào. Cảm ơn bạn.
Shankar Kumar

3
Không chắc chắn tôi hiểu, nếu a là danh sách, và str là thứ phù hợp với, x là gì? Python newbie ftw. :)
đỏ

2
@red: bạn có thể đọc for x in anhư "cho từng thành phần trong danh sách". Vì alà danh sách các chuỗi và xlà một thành phần của danh sách đó, xlà một chuỗi (một trong 'a', 'b', 'c' trong ví dụ ban đầu)
Người dùng

6
@emispowder Nó hoạt động tốt đối với tôi như trong Python 2.6.9.
MPlanchard

67

any()cho đến nay là cách tiếp cận tốt nhất nếu tất cả những gì bạn muốn là Truehoặc False, nhưng nếu bạn muốn biết cụ thể chuỗi / chuỗi nào khớp, bạn có thể sử dụng một vài thứ.

Nếu bạn muốn trận đấu đầu tiên (với Falsemặc định):

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

Nếu bạn muốn nhận tất cả các trận đấu (bao gồm cả trùng lặp):

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

Nếu bạn muốn nhận tất cả các kết quả trùng lặp (bỏ qua thứ tự):

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

Nếu bạn muốn nhận được tất cả các trận đấu không trùng lặp theo đúng thứ tự:

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

vui lòng thêm ví dụ cho trận đấu cuối cùng
Oleg Kokorin

@OlegKokorin: Nó tạo ra một danh sách các chuỗi khớp theo thứ tự mà nó tìm thấy chúng, nhưng nó chỉ giữ lại chuỗi đầu tiên nếu hai chuỗi giống nhau.
zondo

Sử dụng một OrderedDictcó lẽ là hiệu suất hơn một danh sách. Xem câu trả lời này về "Loại bỏ trùng lặp trong danh sách"
wjandrea

44

Bạn nên cẩn thận nếu các chuỗi trong ahoặc strdài hơn. Các giải pháp đơn giản lấy O (S * (A ^ 2)), trong đó Sđộ dài của strvà A là tổng chiều dài của tất cả các chuỗi trong a. Để có giải pháp nhanh hơn, hãy xem thuật toán Aho-Corasick để khớp chuỗi, chạy trong thời gian tuyến tính O (S + A).


Aho-Corasick cũng có thể tìm thấy các chuỗi con thay vì tiền tố?
RetroCode

1
Một số thư viện trăn Aho-Corasick đang ở đâyđây
vorpal

23

Chỉ cần thêm một số đa dạng với regex:

import re

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

hoặc nếu danh sách của bạn quá dài - any(re.findall(r'|'.join(a), str, re.IGNORECASE))


1
Điều này làm việc cho trường hợp sử dụng nhất định của câu hỏi. Nếu bạn tìm kiếm (hoặc *điều này không thành công, vì trích dẫn cú pháp regex cần phải được thực hiện.
guettli

2
Bạn có thể thoát nó nếu cần thiết với '|'.join(map(re.escape, strings_to_match)). Bạn có thể re.compile('|'.join(...))là tốt.
Artyer

12

Bạn cần lặp lại các yếu tố của 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"

2
Vâng, tôi biết làm thế nào để làm điều đó nhưng so với câu trả lời của Marks, đó là mã khủng khiếp.
jahmax

10
Chỉ khi bạn hiểu mã của Mark. Vấn đề bạn gặp phải là bạn không kiểm tra các yếu tố của mảng. Có rất nhiều cách ngắn gọn, pythonic để thực hiện những gì bạn muốn sẽ che giấu bản chất của những gì sai với mã của bạn.
Seamus Campbell

9
Nó có thể là "mã khủng khiếp" nhưng đó chính xác là những gì () làm . Ngoài ra, điều này cung cấp cho bạn chuỗi thực tế khớp, trong khi bất kỳ () nào chỉ cho bạn biết có khớp.
alldayremix

4

jbernadas đã đề cập đến Thuật toán Aho-Corasick để giảm độ phức tạp.

Đây là một cách để sử dụng nó trong Python:

  1. Tải xuống aho_corasick.py từ đây

  2. Đặt nó trong cùng thư mục với tệp Python chính của bạn và đặt tên cho nó aho_corasick.py

  3. Hãy thử alrorithm với mã sau:

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

Lưu ý rằng tìm kiếm phân biệt chữ hoa chữ thường


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

Nó phụ thuộc vào ngữ cảnh giả sử nếu bạn muốn kiểm tra từng chữ như (bất kỳ từ nào a, e, w, .. vv) trong là đủ

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

nếu bạn muốn kiểm tra bất kỳ ký tự nào trong số các từ gốc: hãy sử dụng

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

nếu bạn muốn tất cả các đầu vào bạn muốn trong gốc_word đó, hãy sử dụng tất cả đơn giản

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

Điều gì sẽ là thông tin của bạn? Tôi có thể nhận ra hai điều: câu mà tôi đang tìm kiếm thứ gì đó. Mảng từ tôi đang tìm kiếm. Nhưng bạn mô tả ba biến và tôi không thể hiểu biến thứ ba là gì.
mayid

1

Chỉ cần thêm một số thông tin về cách lấy tất cả các thành phần danh sách có sẵn trong Chuỗi

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

1

Một cách tiếp cận nhanh đáng ngạc nhiên là sử dụng 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")

Điều này hoạt động nếu akhông chứa bất kỳ giá trị nhiều ký tự (trong trường hợp này sử dụng anynhư được liệt kê ở trên ). Nếu vậy, đơn giản hơn để chỉ định alà một chuỗi : 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')

hình ảnh ví dụ đầu ra


0

Tôi sẽ sử dụng loại chức năng này cho tốc độ:

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)));
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.