2017-07-07 100 views
2

我有一个字典,其中字母对应于数字和字符串,并且如果每个字母出现在字符串中的次数等于或等于少于字典中与该字母相关的数字。当这个问题不那么复杂并且没有计算事件发生的限制时,我使用all(x in string for x in dictionary)。有没有类似的简洁的方式来测试这个基于字典中的int值?确定是否可以从另一个字符串中的字符子集创建一个字符串

编辑:道歉,这是我们正在看。如果我现在需要它,除非该字母出现的次数是<返回False 字符串中的字母任何实例都显示为手,一本字典关键

def isValidWord(word, hand, wordList): 
    """ 
    Returns True if word is in the wordList and is entirely 
    composed of letters in the hand. Otherwise, returns False. 

    Does not mutate hand or wordList. 

    word: string 
    hand: dictionary (string -> int) 
    wordList: list of lowercase strings 
    """ 
    if word.lower() in wordList and all(x in hand for x in word): 
     return True 
    else: 
     return False 

此代码返回True =的该键的整数值。我已经非常混乱地完成了这个任务,并且想知道是否有办法将这种特定级别的特征合并到all方法或类似的简洁方法中。

+0

请向我们提供样本输入和预期输出。你的问题还不够完整,无法给出明确的答案。 – abccd

+0

请发布您的一些数据,以及您期望从中获得什么? –

+0

对不起,有一个带有docstring的代码块 – Max

回答

1

从您的文档字符串中,您试图确定word是否可以使用hand中的字母组成。这是非常直接的使用collections.Counter。你甚至不需要制作hand字典。

def is_valid_word(word, hand, word_list): 
    wc, hc = Counter(word), Counter(hand) 
    return word.lower() in word_list and all(wc[k] <= hc[k] for k in wc) 

如果你想保持hand作为一本字典,只需要使用hand代替hc线下决赛,而忽略它变成一个Counter

这在复杂性方面并不是最佳的,但是可以使用相同的总体思想来编写一个好的算法。请注意,这比使用count更有效,因为每个字符串只需要对每个唯一字母进行一次而不是一次迭代。

一个更有效的功能来检查,这可能看起来像:

def is_partial_anagram(word, pool): 
    pool_counter = Counter(pool) 
    for c in word: 
     if not pool_counter[c]: 
      return False 
     pool_counter[c] -= 1 
    return True 

的复杂性在这里是渐近相同,但将返回False越早当没有比赛和避免建设者word一个Counter

1

如果我理解正确的你,你的hand字典形成,如:

hand = {"f": 1, "o": 2, "b": 1, "a": 1, "r": 1, "z": 0} 

而且你希望它匹配foobar但不bazz设置为0,并至少有一个z。你可以做,使用str.count()喜欢:

def isValidWord(word, hand, wordList): 
    if word.lower() in wordList and all(hand.get(x, 0) >= word.count(x) for x in set(word)): 
     return True 
    else: 
     return False 

不是最有效的,但应该给你的想法。您可以使用以下方式对其进行测试:

hand = {"f": 1, "o": 2, "b": 1, "a": 1, "r": 1, "z": 0} # letters with their allowed counts 
word_list = ["foo", "bar", "baz"] # allowed words 

print(isValidWord("foo", hand, word_list)) # True 
print(isValidWord("bar", hand, word_list)) # True 
print(isValidWord("baz", hand, word_list)) # False 
+0

这可以通过省略'x in hand'然后使用'hand.get(x,0)'稍微简化一些。 –

+0

@JaredGoguen - 公平点。更新。 – zwer

相关问题