Сравнить список кортежей, подтвердить подмножество на основе условия? - PullRequest
0 голосов
/ 05 июня 2018

Учитывая слово и список слов, я должен найти элементы / слова списка, которые можно составить, используя буквы (количество букв) данного слова.Я попытался использовать объект Counter из коллекций и определение функции cmp() Python 2.7 (я использую 3.6.5).

С тех пор я пришел к выводу, что этот подход кажется плохой практикой для такой проблемы (ранее я пытался использовать счетчики объектных словарей для сравнения).Причина, по которой моя программа не работает, заключается в том, что compare_fn полагается на операции «>», «<» между списками, которые дают результат на основе лексикографического порядка (<a href="https://stackoverflow.com/questions/13052857/comparing-two-lists-using-the-greater-than-or-less-than-operator"> указано здесь ).Таким образом, даже если «raven» можно сделать из «ravenous», приведенная ниже программа не будет выполнена из-за порядка символов в отсортированном списке.

from collections import Counter    
word = 'ravenous'
candidates = ["raven", "mealwheel", "rasputin"]

def count_fn(mystr):
    return sorted(list(Counter(mystr).items()))

def compare_fn (c1,c2):
    return ((c1>c2) - (c1<c2))

list_word =  count_fn(word)
list_candidates = list(map(count_fn,candidates))
cmp_list = [compare_fn(list_word,i) for i in list_candidates]
cmp_list
#[-1, -1, -1]    #should be [1,-1,-1]

Итак, как подтвердить два списка ниже, как я могу подтвердитьчто list_candidates[0] является подмножеством list_word.Обратите внимание, что сравнение ('a',1) в list_word против ('a',1) в list_candidates[i] также может составлять ('a',5) в list_word против ('a',1) в list_candidates[i];оба случая верны.

print(list_word)
#[('a', 1), ('e', 1), ('n', 1), ('o', 1), ('r', 1), ('s', 1), ('u', 1), ('v', 1)]
print(list_candidates[0])
#[('a', 1), ('e', 1), ('n', 1), ('r', 1), ('v', 1)]

1 Ответ

0 голосов
/ 05 июня 2018

Я считаю использование счетчиков хорошим выбором.Не превращайте их в списки.Я намеренно возвратил [True, False, False] вместо [1, -1, -1], но вы можете легко это изменить.

Более того: я использовал понимание списка вместо карты, потому что это большетекущий в python, но семантика та же.

from collections import Counter
word = 'ravenous'
candidates = ["raven", "mealwheel", "rasputin"]

def count_fn(mystr):
    return Counter(mystr)

def compare_fn (c1,c2):
    return all(c1[char] >= count for char, count in c2.items())

counter_word =  count_fn(word)
list_candidates = [count_fn(candidate) for candidate in candidates]
cmp_list = [compare_fn(counter_word, i) for i in list_candidates]
print(cmp_list)
...