确定字符串是否是等值线图

时间:2017-01-26 09:51:04

标签: python

任务
编写一个程序,检查作为参数提供的单词是否为Isogram。 Isogram是一个不会出现多次字母的单词。

创建一个名为is_isogram的方法,它接受一个参数,一个单词来测试它是否是等值线图。这个方法应该返回一个单词的元组和一个布尔值,指示它是否是等值线。

如果提供的参数是空字符串,则返回参数并返回False :(参数,False)。如果提供的参数不是字符串,则引发一个TypeError,并显示消息'Argument should a a string'。

示例:

is_isogram("abolishment")

预期结果:

("abolishment", True)

可见测试

from unittest import TestCase

class IsogramTestCases(TestCase):
  def test_checks_for_isograms(self):
    word = 'abolishment'
    self.assertEqual(
      is_isogram(word),
      (word, True),
      msg="Isogram word, '{}' not detected correctly".format(word)
    )

  def test_returns_false_for_nonisograms(self):
    word = 'alphabet'
    self.assertEqual(
      is_isogram(word),
      (word, False),
      msg="Non isogram word, '{}' falsely detected".format(word)
    )

  def test_it_only_accepts_strings(self):
    with self.assertRaises(TypeError) as context:
      is_isogram(2)
      self.assertEqual(
        'Argument should be a string',
        context.exception.message,
        'String inputs allowed only'
      )

我的解决方案:

def is_isogram(word):
    if type(word) != str:
        raise TypeError('Argument should be a string')

    elif word == "":
      return (word, False)
    else:
        word = word.lower()
        for char in word:
            if word.count(char) > 1:
                return (word, False)
            else:
                return (word, True) 

但是它的功能拒绝通过一些隐藏的测试:我的解决方案出了什么问题?还有另一种优雅的方式来编写这个函数吗?

12 个答案:

答案 0 :(得分:5)

我不确定您的搜索应该不区分大小写,因此您可能应该删除word = word.lower(),但主要问题是return终止该函数,因此您当前的代码只需要{{1}在所有测试完成后(即在循环之外):

return True

无论如何,更好的方法是使用for char in word: if word.count(char) > 1: return (word, False) return (word, True) 删除字符串中的所有重复项,然后比较长度;还可以使用set()来检查isinstance()是否为字符串。您可以使用word检查空字符串。您不需要使用if w括号,逗号足以return元组:

return

示例:

def is_isogram(word):
    if isinstance(word,str):
        w = word.lower() # assuming you want a case in-sensitive search
        return word, len(w) == len(set(w)) if w else False
    else:
        raise TypeError('Argument should be a string')

答案 1 :(得分:2)

我试过这样的方式:

def isogram(n):
 if not isinstance(n, str):
    return n,False
 elif len(n) < 1:
    return n,False
 n = n.lower()
 if len(n) == len(set(n)):
    return n,True
 else:
    return n,False
  • 第二行检查输入n是否为字符串,如果不是,则返回False。
  • 第4行检查输入的长度是否小于1,在这种情况下输入为空,我们无法检查是否是等值线。
  • &#39; n = n.lower()&#39;第6行确保输入变为带小写字母的字符串。
  • 在第7行,我们检查输入的长度是否等于set(n)的长度。函数set()将集合或序列或迭代器对象转换为集合。例如:设置(&#39;列表&#39;)返回{&#39; s&#39;&#39; t&#39;,&#39; l&#39;,&#39; i&#39 ;},你可以看到这封信的字母&#39;在&#39;列表&#39;中出现两次,不会出现在集合中。这对于检查集合的长度是否等于输入的长度很有用,如果在输入中有一个字母出现两次,则条件为False。

我希望这个解释能使脚本清晰。

答案 2 :(得分:1)

原因

“但是这个函数拒绝通过一些隐藏的测试:我的解决方案出了什么问题?是否有另一种优雅的方式来编写这个函数?”

即拒绝通过测试非常简单。

elif word == "": 

应该是

elif word == " ":

根据单元测试

if argument==" " :
    return(argument,False)

你忘记了空白。希望这有助于下一个搜索的人。

答案 3 :(得分:1)

这对我有用。如果位数不止一个,它将被添加到新字符串中。如果此新字符串为空,则该函数将返回True。其他错误。只有“ if word.count(char)> 1:”才能执行此操作。至少不适合我。

def isagram (word):
    if not isinstance(word, str):
        return (False, word)
    if not word:
        return (False, word)
    word.lower()
    multi_char = ''
    for char in word:
        if word.count(char) > 1:
            multi_char += char
    return (False, word) if multi_char else (True, word)

答案 4 :(得分:0)

以下是解决问题的一种方法:

def is_isogram(argument):
  word_seen=set()
  if type(argument) != str:
    raise TypeError('Argument should be a string')
  if argument==" " :
    return(argument,False)
  argument.lower()
   for letter in argument:
    if letter in word_seen:
      return(argument,False)
    word_seen.add(letter)
  return (argument,True)

同样,我也尝试了以下方法来删除字符串中的所有空格:

def is_isogram(argument):
  word_seen=set()
  if type(argument) != str:
    raise TypeError('Argument should be a string')
  if argument==" " :
    return(argument,False)
  argument.lower()
  argument = ''.join(argument.split())
  for letter in argument:
    if letter in word_seen:
      return(argument,False)
    word_seen.add(letter)
  return (argument,True)

答案 5 :(得分:0)

我在这里解决了:

def is_isogram(word):

for letter in word:
    if word.count(letter) > 1:
        return False
else:
    return True

print is_isogram(&#34; Hello&#34;)

答案 6 :(得分:0)

def is_Isogram(words):
cover_words = words.lower()

letter_list = []

for letter in cover_words:
    if letter.isalpha():
        if letter in letter_list:
            return False
        letter_list.append(letter)
return True

if __name__ == '__main__':
      print(is_Isogram('Machine'))
      print(is_Isogram('Geeks'))`

答案 7 :(得分:0)

def is_isogram(string):
    if type(string) != str:
        raise TypeError('Argument should be a string')
    elif string == " ":
        return (string, False)
    else:
        for i in string:
            if string.count(i) > 1:
                return (string, False)
    return (string, True)

答案 8 :(得分:0)

这是建议的解决方案的最后一部分:

    for char in word:
        if word.count(char) > 1:
            return (word, False)
        else:
            return (word, True) 

return将结束该函数,因此for循环将始终在计算第一个字母的重复次数后退出,而从不检查其他字母。

如果您的单词的第一个字母是唯一的,则该函数将返回True。

我相信这是一个错误,这是我的更正建议:

    for char in word:
        if word.count(char) > 1:
            return (word, False)
    return (word, True) 

答案 9 :(得分:0)

import collections

def is_isogram(word):
    if not isinstance(word, str):
        raise TypeError('Argument should be a string')
    most_common = collections.Counter(word).most_common(1)
    if most_common:
        char, freq = most_common[0]
        return (word, freq == 1)
    else:
        return (word, False)

答案 10 :(得分:-1)

您只需要一个额外的条件语句来检查单词中的字符是否只是字母(即没有数字或符号),同时检查字符是否重复:

def is_isogram(word):
    if type(word) != str:
        raise TypeError("Argument should be a string")
    if len(word) < 1:
        return (word, False)
    word = word.lower()

    for char in word:
        if word.count(char) > 1 or \
        char not in "abcdefghijklmnopqrstuvwxyz":  # this checks that the char is an alphabet
            return (word, False)
    return (word, True)

我想这应该会有所帮助。

答案 11 :(得分:-1)

我发现这是正确的  

    def is_isogram(word):
if type(word)!=str: raise TypeError("Argument should be a String") elif word.strip()=="": return(word,False) else: word =word.lower() for char in word: if word.count(char) >1: return (word ,False) else: return(word ,True)