2012-03-14 18 views
2

のリストの中で最もマッチした文字列検索するには:Pythonの:どのように私は私が必要なものを詳細に説明しよう弦

を私はfeedparserを使用してPythonでRSSフィードを解析しています。このフィードには、もちろん、一般的なRSSフィードと同様に、タイトル、リンク、説明付きの項目のリストがあります。

一方、アイテムの説明で見つけ出す必要のあるキーワードを含む文字列のリストがあります。

RSSフィード

<channel> 
    <item> 
     <title>Lion</title> 
     <link>...</link> 
     <description> 
      The lion (Panthera leo) is one of the four big cats in the genus 
      Panthera, and a member of the family Felidae. 
     </description> 
    </item> 
    <item> 
     <title>Panthera</title> 
     <link>...</link> 
     <description> 
      Panthera is a genus of the Felidae (cats), which contains 
      four well-known living species: the tiger, the lion, the jaguar, and the leopard. 
     </description> 
    </item> 
    <item> 
     <title>Cat</title> 
     <link>...</link> 
     <description> 
      The domestic cat is a small, usually furry, domesticated, 
      carnivorous mammal. It is often called the housecat, or simply the 
      cat when there is no need to distinguish it from other felids and felines. 
     </description> 
    </item> 
</channel> 

キーワードリスト

['cat', 'lion', 'panthera', 'family'] 
:私がする必要がどのような

は、ほとんどのキーワードマッチ

例を持っているアイテムを見つけるです

この場合、4つのキーワードがすべて含まれているため、(唯一の 'cat'ではなく 'cats'とは関係ありません。)リテラルキーワード

私はいくつかの説明に 'cat'キーワードが100回(他のキーワードはありません)含まれていても、ほとんどのキーワードを探しているのでこれは勝者にはならないことを明確にしましょう、キーワードが表示される回数はほとんどありません。

今、私はrss項目をループして、「手動で」、キーワードが表示された回数を数えます(ただし、上記の問題があります)。

私はPythonで非常に新しく、別の種類の言語(C#)から来ているので、これはかなり些細なことですが残念です。

どのようにこの問題にアプローチしますか?

+0

以下の回答すべての偉大ですが、部分的な一致を注意してください( '' cat'の発生などconcatenate'、カウントしていますか?)と大文字( '猫を行います'合致としてカウントする、' CAT'についてはどうすればよい?) –

+0

はい、 '連結'は 'cat'の出現としてカウントし、大文字と小文字を区別する必要はありません。警告をありがとう。 – emzero

答えて

3
texts = [ "The lion (Panthera leo) ...", "Panthera ...", "..." ] 
keywords = ['cat', 'lion', 'panthera', 'family'] 

# gives the count of `word in text` 
def matches(text): 
    return sum(word in text.lower() for word in keywords) 

# or inline that helper function as a lambda: 
# matches = lambda text:sum(word in text.lower() for word in keywords) 

# print the one with the highest count of matches 
print max(texts, key=matches) 
+0

すばらしい解決策。このコードのしくみを少し説明していただけますか?私は現在、Pythonでラムダについて読んでいます。 – emzero

+0

小文字に変換されています。 –

+0

@ NiklasB。はい、あなたは正しいです。私はmax関数の 'texts'引数を '[x.lower()for x for texts] 'の代わりに置き換えました。 – emzero

0

その他の回答は非常にエレガントですが、実際のところは単純すぎるかもしれません。それらが壊れるかもしれないいくつかの方法は以下を含みます:

  • 部分的な単語のマッチング - 'cat'は 'concatenate'に一致する必要がありますか? 「猫」はどうですか?
  • 大文字と小文字の区別 - 'cat'は 'CAT'と一致する必要がありますか?キャットはいかがですか?

私の解決策では、これらの両方のケースが可能です。

import re 

test_text = """ 
Cat? 

The domestic cat is a small, usually furry, domesticated, 
carnivorous mammal. It is often called the housecat, or simply the 
cat when there is no need to distinguish it from other felids and felines. 
""" 

wordlist = ['cat','lion','feline'] 
# Construct regexp like r'\W(cat|lionfeline)s?\W' 
# Matches cat, lion or feline as a whole word ('cat' matches, 'concatenate' 
# does not match) 
# also allow for an optional trailing 's', so that both 'cat' and 'cats' will 
# match. 
wordlist_re = r'\W(' + '|'.join(wordlist) + r')(s?)\W' 

# Get list of all matches from text. re.I means "case insensitive". 
matches = re.findall(wordlist_re, test_text, re.I) 

# Build list of matched words. the `[0]` means first capture group of the regexp 
matched_words = [ match[0].lower() for match in matches] 

# See which words occurred 
unique_matched_words = [word for word in wordlist if word in matched_words] 

# Count unique words 
num_unique_matched_words = len(unique_matched_words) 

出力は次のようである:

>>> wordlist_re 
'\\W(cat|lion|feline)(s?)\\W' 
>>> matches 
[('Cat', ''), ('cat', ''), ('cat', ''), ('feline', 's')] 
>>> matched_words 
['cat', 'cat', 'cat', 'feline'] 
>>> unique_matched_words 
['cat', 'feline'] 
>>> num_unique_matched_words 
2 
>>> 
+0

質問によれば、部分一致は大丈夫であり、検索では大文字と小文字を区別しません。 –

+0

Sidenote:大文字小文字を区別しないregexpsは、時にはバックトラックのために遅くなることがあります。文字列全体を最初に 'lower() 'することはできますが、Unicode文字列(' 'Главноевновостях'.lower () '?) –

+0

@NiklasB。ああ、私は小冊子を読まなかった。 –

関連する問題