确定“字符串”是否为等距图

时间:2018-08-09 16:19:38

标签: python pattern-matching

要确定字符串是否为等轴测图:

  

确定单词或短语是否为等距图。等轴测图(也称为   “非模式词”)是没有重复字母的词或短语,   但是,空格和连字符可以多次出现。

我的尝试

def is_isogram(string):
    word = string.lower()

    if word == "":
        return False
    elif word == " ":
        return False
    else:
        for char in word:
            if (word.count(char) > 1) and (char != " " or char != "-") and (len(word) > 0):
                return False
            else:
                return True

但是,当传递给函数的字符串为空并且两个中心字符相同时,此操作将失败。

这些是单元测试:

import unittest
from isogram import is_isogram

class IsogramTest(unittest.TestCase):

    def test_empty_string(self):
        self.assertIs(is_isogram(""), True)

    def test_isogram_with_only_lower_case_characters(self):
        self.assertIs(is_isogram("isogram"), True)

    def test_word_with_one_duplicated_character(self):
        self.assertIs(is_isogram("eleven"), False)

    def test_word_with_one_duplicated_character_from_end_of_alphabet(self):
        self.assertIs(is_isogram("zzyzx"), False)

    def test_longest_reported_english_isogram(self):
        self.assertIs(is_isogram("subdermatoglyphic"), True)

    def test_word_with_duplicated_character_in_mixed_case(self):
        self.assertIs(is_isogram("Alphabet"), False)

    def test_hypothetical_isogrammic_word_with_hyphen(self):
        self.assertIs(is_isogram("thumbscrew-japingly"), True)

    def test_isogram_with_duplicated_hyphen(self):
        self.assertIs(is_isogram("six-year-old"), True)

    def test_made_up_name_that_is_an_isogram(self):
        self.assertIs(is_isogram("Emily Jung Schwartzkopf"), True)

    def test_duplicated_character_in_the_middle(self):
        self.assertIs(is_isogram("accentor"), False)

    # Additional tests for this track

    def test_isogram_with_duplicated_letter_and_nonletter_character(self):
        self.assertIs(is_isogram("Aleph Bot Chap"), False)


if __name__ == '__main__':
    unittest.main()

为这两个测试用例提供服务时,我做错了什么?

3 个答案:

答案 0 :(得分:5)

使用collections.Counterstring.ascii_lowercase仅检查字母字符要简单得多:

from collections import Counter
from string import ascii_lowercase

def is_isogram(s:str) -> bool:
  c = Counter(s.lower())
  return all(c[i] < 2 for i in ascii_lowercase)

tests = [('', True), ('isogram', True), ('eleven', False), ('zzyzx', False), ('subdermatoglyphic', True), ('Alphabet', False), ('thumbscrew-japingly', True), ('six-year-old', True), ('Emily Jung Schwartzkopf', True), ('accentor', False), ('Aleph Bot Chap', False)]
for a, b in tests:
  assert is_isogram(a) == b

print('all tests passed')

输出:

all tests passed

答案 1 :(得分:2)

您可以使用re.sub删除允许重复的字符,然后比较list(your_string)set(your_string)的长度。

import re
def is_isogram(s):
    s = re.sub(' |-|_', '', s)
    return len(set(s)) == len(list(s))

关于哪里出错了:
您先明确说出if word == "": return False,然后再说self.assertIs(is_isogram(""), True),所以我希望这是一个简单的错误,您可以用一种方法或另一种方法来解决。 只要第一个字符不重复,它就会失败,因为如果第一个字符不是重复的,则for char in word循环将返回True。检查所有字符后,您可能希望使用return True

答案 2 :(得分:1)

好吧,您的错误出在:

(1)

if word == "":
    return False
...

和(2)

char != " " or char != "-"

和(3)

else:
    return True

(1):您的测试表明一个空字符串是一个等距图,因此此if应该返回True

(2):这是重言式,因为它将始终返回True。考虑一下您的char为空白的情况,则char != " "将为False,但是char != "-"将返回True,而True or FalseTrue

(3):如果字符串的第一个字母没有重复,则返回True,而不解析字符串的其他字母。因此,只有在for循环结束时,才应将此返回值放回去。

因此,修复此问题后,您的代码将可以正常工作:

def is_isogram(string):
    word = string.lower()

    if word == "":
        return True
    elif word == " ":
        return False
    else:
        for char in word:
            if word and char not in ' -' and word.count(char) > 1:
                return False
        return True

测试结果:

...........
----------------------------------------------------------------------
Ran 11 tests in 0.000s

OK

PS:您也可以按照@ Ajax1234和@MoxieBall的建议,将此代码重写为一个更简单的代码。

或者您可以执行以下操作:

def is_isogram(word):
    filtered_word = filter(lambda x: x not in ' -', word.lower())
    return len(filtered_word) == len(set(filtered_word))