2014-11-25 89 views
0

我试图做一个方法,它可以检查给定的短语是否至少匹配短语列表中的一个项目并返回它们。输入是短语,短语列表和同义词列表的词典。重点是使其具有普遍性。按给定的短语返回匹配列表

这里是例子:

phrase = 'This is a little house' 
dictSyns = {'little':['small','tiny','little'], 
      'house':['cottage','house']} 
listPhrases = ['This is a tiny house','This is a small cottage','This is a small building','I need advice'] 

我可以创建一个代码,可以做到这一点在这个例子中,它返回布尔:

if any('This'+' '+'is'+' '+'a'+x+' '+y == phrase for x in dictSyns['little'] for y in dictSyns['house']): 
    print 'match' 

的第一点是,我要创建功能这将是普遍的(取决于结果)。第二个是我想要这个函数返回匹配短语的列表。

你能给我一个建议如何做到这一点,所以在这种情况下该方法返回['This is a tiny house','This is a small cottage']

输出将是这样的:

>>> getMatches(phrase, dictSyns, listPhrases) 
['This is a tiny house','This is a small cottage'] 

回答

1

我将接近这个如下:

import itertools 

def new_phrases(phrase, syns): 
    """Generate new phrases from a base phrase and synonyms.""" 
    words = [syns.get(word, [word]) for word in phrase.split(' ')] 
    for t in itertools.product(*words): 
     yield ' '.join(t) 

def get_matches(phrase, syns, phrases): 
    """Generate acceptable new phrases based on a whitelist.""" 
    phrases = set(phrases) 
    for new_phrase in new_phrases(phrase, syns): 
     if new_phrase in phrases: 
      yield new_phrase 

代码的根是words的分配,在new_phrases,其将所述phrasesyns变成更有用的形式,其中每个元素是该单词的可接受选项的列表的列表:

>>> [syns.get(word, [word]) for word in phrase.split(' ')] 
[['This'], ['is'], ['a'], ['small', 'tiny', 'little'], ['cottage', 'house']] 

注意以下几点:

  • 使用发电机用大量的组合(未建立整个列表一次)的更有效的处理;
  • 使用set进行高效(O(1),与O(n)进行列表)成员资格测试;
  • 使用itertools.product生成基于synsphrase的可能组合(您也可以在执行此操作时使用itertools.ifilter);和
  • Style guide合规。

在使用中:

>>> list(get_matches(phrase, syns, phrases)) 
['This is a small cottage', 'This is a tiny house'] 

事情要考虑:

  • 什么字符的情况下(例如应如何"House of Commons"进行治疗)?
  • 标点符号怎么样?
+0

谢谢,它帮助很大。非常好的方法。例:我会改变这一行:如果new_phrase.lowercase()在[x.lowercase()for x in短语中] ..标点符号(昏迷和点):我会使用.strip(',').strip('。 ') – 2014-11-25 10:55:30

+1

@Milan指出你的小写处理方式效率极低,因为它为每个'new_phrase'重新处理'短语',不使用'set',并且在生成新短语时不包括小写字母。您还必须仔细考虑在哪个步骤“剥离”(注意,您可以仅剥离(“,。”)')。 – jonrsharpe 2014-11-25 10:57:22

0

我就这样理解:

for value in dictSyns: 
    phrase = phrase + dictSyns[value] 

for each_phrase in listPhrases: 
    if any(word not in phrase for word in each_phrase.split()): 
     pass 
    else: 
     print each_phrase 

大概没有巨大的效率。它创建可接受的单词列表。然后它将每个字符串中的每个单词与该列表进行比较,如果没有不可接受的单词,则会打印该短语。

编辑:我也意识到这并不检查语法意义。例如,“小小这个a”这个短语仍然会正确返回。它只是检查每个单词。我会在这里留下来显示我的耻辱。

相关问题