【问题标题】:Class wordplay with four methods四种方法的课堂文字游戏
【发布时间】:2019-08-07 14:46:47
【问题描述】:

我有以下问题和两个非常重要的问题。 编写一个名为 Wordplay 的课程。它应该有一个包含单词列表的字段。用户 类的应该将他们想要使用的单词列表传递给类。应该有 以下方法:

  • words_with_length(length) — 返回长度为 length 的所有单词的列表
  • starts_with(s) — 返回所有以 s 开头的单词的列表
  • ends_with(s) — 返回所有以 s 结尾的单词的列表
  • palindromes() — 返回列表中所有回文的列表

第一个问题。编译我的程序后,方法以返回相同的单词开始和结束。 下一个问题。在这种情况下,我创建了一个包含三个名称的列表。但是,如果我想询问列表大小并在要求输入单词时对其进行迭代怎么办。我该如何实现这个想法?

class Wordplay:

  def __init__(self):
    self.words_list=[]

  def words_with_lenght(self,lenght):
    for i in range(0,len(self.words_list)-1):
      if len(self.words_list[i])==lenght:
        return self.words_list[i]

  def starts_with_s(self,s):
    for i in range(0,len(self.words_list)-1):
      if s.startswith('s')==True:
        return self.words_list[i]

  def ends_with_s(self,s):
    for i in range(0,len(self.words_list)-1):
      if s.endswith('s')==True:
        return self.words_list[i]

  def palindromes(self):
    for i in range(0,len(self.words_list)-1):
      normal_word=self.words_list[i]
      reversed_word=normal_word[::-1]
      if reversed_word==normal_word:
        return reversed_word

verification=Wordplay()
verification.words_list=['sandro','abba','luis']
lenght=int(input('Digit size you want to compare\n'))
s='s'
print(verification.words_with_lenght(lenght))
print(verification.starts_with_s(s))
print(verification.ends_with_s(s))
print(verification.palindromes())

如果我输入例如尺寸 4,我希望结果是: 阿巴,路易斯;桑德罗;路易斯;阿爸而不是—— 阿爸;桑德罗;桑德罗;阿爸

【问题讨论】:

    标签: python string class


    【解决方案1】:

    if s.startswith('s')==True: 行中,您已将字符串"s" 传递给函数,结果是

    if 's'.startswith('s')==True: 
    #  ^^^
      return self.words_list[i]
    

    此条件始终为真。您可能根本不需要这里的参数,因为作业要求您使用 hard code "s"。您可以使用:

    if self.words_list[i].startswith('s'): 
        return self.words_list[i]
    

    请注意,一旦找到匹配项,上面的示例就会使用return。这是个问题。这个程序中的循环提前中断,一旦找到一个匹配项就从函数中返回。您可能打算将每个成功的匹配附加到列表并返回结果列表或使用yield 关键字返回generator(但如果调用者想要来自生成器的持久列表,则需要使用list() )。使用列表构建结果如下所示:

    result = []
    
    for i in range(len(self.words_list)):
        if self.words_list[i].startswith('s'): 
            result.append(self.words_list[i])
    
    return result
    

    另一个问题:这个程序中的循环不会遍历它们各自的列表。 range() 函数包含开头但不包含结尾,因此您可能打算使用 range(len(self.words_list)) 而不是 range(0, len(self.words_list) - 1)

    除此之外,我想提出一些设计和风格要点:

    • 在运算符之间使用水平空格并在块周围使用垂直空格。

      foo=bar.corge(a,b,c)
      if foo==baz:
        return quux
      

      更清晰
      foo = bar.corge(a, b, c)
      
      if foo == baz:
          return quux
      
    • 使用 4 个空格而不是 2 个空格进行缩进,这样更容易快速确定哪个代码在哪个块中。

    • 首选for element in my_list 而不是for i in range(len(my_list))。如果需要索引,大多数情况下可以使用for i, elem in enumerate(my_list)。更好的是,使用list comprehensions 执行过滤操作,这是大部分逻辑。
    • 没有必要使用if condition == Trueif condition 就足够了。您可以简化令人困惑和不准确的逻辑,例如:

      def palindromes(self):
        for i in range(0,len(self.words_list)-1):
          normal_word=self.words_list[i]
          reversed_word=normal_word[::-1]
          if reversed_word==normal_word:
            return reversed_word
      

      例如:

      def palindromes(self):
          return [word for word in self.words_list if word[::-1] == word]
      

      也就是说,尽可能避免使用中间变量和索引。

    • 我意识到您可能与设计有关,但我觉得这是编写实用程序类的一种奇怪方式。作为对可迭代对象进行操作的静态方法,它会更加灵活。典型用法可能如下:

      from Wordplay import is_palindrome
      
      is_palindrome(some_iterable)
      

      代替:

      wordplay = Wordplay(some_iterable)
      wordplay.palindromes()
      

      我的理由是这个类基本上是无状态的,所以在不需要状态时强加状态似乎很奇怪。这有点主观,但值得注意(如果您曾经使用过mathrandom 模块,那么想法是一样的)。

      构造函数中缺少参数更奇怪;班级的客户必须以某种方式神奇地“知道”words_list 是他们需要进行分配以填充班级状态的内部变量名。这个变量名应该是客户不知道的实现细节。未能在初始化函数中提供参数,该字段应该有一个设置器(或完全跳过内部状态)。

    • ends_with_s(self, s) 是一个愚蠢的函数;似乎设计师在想写ends_with(self, letter)ends_with_s(self) 之间感到困惑(前者更可取)。如果你想要一封新信怎么办?您是否需要为每个可能的结尾字符ends_with_aends_with_bends_with_c 等编写几十个函数?我意识到这只是一个人为的作业,但课程的设计仍然很糟糕。

    • 拼写错误:words_with_lenght -> words_with_length


    以下是关于如何培养定位这些问题的技能的一般提示:分小块工作并经常运行您的程序。看起来这四个函数是一次性编写的,没有在整个过程中测试每个函数以确保它首先工作。这很明显,因为在所有四个函数中都重复了相同的错误。

    【讨论】:

    • 感谢您的帮助。我正在借助《Python 实用介绍》这本书来学习 Python。我有 2 个月的编程技能。显然,我没有(至少按照今天的标准)减少混乱的技能,或者我也没有以更简单的方式编写代码的技能。我认为这将伴随多年的练习,但是我写了很多行,而我最多只能写一两行。
    • 你做得很好。简单会随着实践而来,我希望所有这些都是非个人的。祝你的代码好运!
    • 我没有得到“逐字逐句”
    • Check this out 或其他关于列表推导的教程。它是先进的,所以如果你不习惯它就不需要使用它——它只是一个附加到列表的循环的简写,带有一个可选的条件来过滤掉项目。
    【解决方案2】:

    s.endswith('s') 将您的输入字符串s(“s”)与"s" 进行比较。 “s”以“s”结尾,所以它总是返回你的第一个条目。将其更改为 if self.words_list[i].startswith('s'):endswith 相同)。

    我建议更改你的 for 循环以迭代单词本身:

    def ends_with_s(self, s):
        for word in self.words_list:
            if word.endswith('s'):
                return word
    

    输入您描述的值列表:

    amount = int(input("How many words? "))
    words = [input("Word {}".format(i + 1)) for i in range(amount)]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-03
      • 2011-12-13
      • 2022-11-04
      • 1970-01-01
      • 1970-01-01
      • 2020-08-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多