【问题标题】:Counting issue wth Python dictionariesPython字典的计数问题
【发布时间】:2019-03-01 07:59:59
【问题描述】:

所以我试图在这个函数中计算唯一的字母。如果它们是唯一的字母,则返回 True,如果没有则返回 False。在“编程”这个词中 有两个 r 和两个 m 和两个 g。它在实际答案为 False 的情况下返回 True?我的逻辑错了吗?

def unique_chars_in_string(input_string):
    unique_chars = {}
    if input_string == "":
        return True

    for letter in input_string:
        if letter in unique_chars:
            unique_chars[letter]+=1
        else:
             unique_chars[letter]=1


    for k in unique_chars:
        if unique_chars[k] > 1:
            return False

        else:
            return True


print(unique_chars_in_string('Programming'))

【问题讨论】:

  • 问题正在返回 True,只要某个字母不存在多次...尝试PProgramming...
  • return all(k == 1 for k in unique_chars.values())

标签: python dictionary counting


【解决方案1】:

根据您的算法,您只是检查字符串的第一个字符。而不是整个字符串。

这段代码有错误的逻辑:

for k in unique_chars:
    if unique_chars[k] > 1:
        return False

    else:
        return True

for 循环中不需要 else 条件。

试试这个:

def unique_chars_in_string(input_string):
    unique_chars = {}
    if input_string == "":
        return True

    for letter in input_string:
        if letter in unique_chars:
            unique_chars[letter]+=1
        else:
             unique_chars[letter]=1


    for k in unique_chars:
        if unique_chars[k] > 1:
            return False

    return True


print(unique_chars_in_string('Programming'))

因此,如果任何字符的计数超过 1,您的代码将返回 false,否则将返回 true

另外,检查Jean-François Fabre's answer 这个问题,它是一个简短而甜蜜的 Pythonic 实现。

编码愉快! :)

【讨论】:

    【解决方案2】:

    如果您想检查所有字母是否只出现一次,请使用all

    return all(k == 1 for k in unique_chars.values())
    

    这将避免在您没有扫描其余字母时过早返回结果。

    还可以考虑使用 collections.Counter 计算您的字母,这是一个专门用于计算可散列元素的字典:

    unique_chars = collections.Counter(input_string)
    

    所以合并成一行:

    return all(k == 1 for k in collections.Counter(input_string).values())
    

    也就是说,我们错过了重点。如果我们需要检查一个单词是否有不重复的字母,这可以使用set 不计算来完成:

    return len(input_string) == len(set(input_string))
    

    【讨论】:

      【解决方案3】:
      for k in unique_chars:
          if unique_chars[k] > 1:
              return False
      
          else:
              return True
      

      这是你的问题。这将检查 unique_chars 中的 any 值是否大于 1, first 值是否为 1 或小于 1。你应该这样做:

      for k in unique_chars:
          if unique_chars[k] > 1:
              return False
      return True  # since this is after the for loop, it only runs if
                   # no character has a count greater than one.
      

      或者,使用set 可以提高效率。

      seen = set()
      for c in input_string:
          if c in seen:
              return False
          seen.add(c)
      return True
      

      【讨论】:

        【解决方案4】:

        当您遇到第一个唯一字符时,您在循环中返回得太早。你只知道在循环结束时所有都是唯一的:

        def unique_chars_in_string(input_string):
            unique_chars = {}
            for letter in input_string:
                if letter in unique_chars:
                    unique_chars[letter]+=1
                else:
                     unique_chars[letter]=1
        
            for k in unique_chars:
                if unique_chars[k] > 1:
                    return False  # not all are unique -> return early
            # but only when all have been checked, can you know for sure all are
            return True
        

        整个函数可以缩短,使用collections.Counterall,但保持底层算法:

        from collections import Counter
        
        def unique_chars_in_string(input_string):
            return all(v==1 for v in Counter(input_string).values())
        

        甚至更简单:

        def unique_chars_in_string(input_string):
            return len(input_string) == len(set(input_string))
        

        【讨论】:

          【解决方案5】:
          s = 'Programming'
          
          a = [True for i in s if s.count(i) > 1]
          if any(a):
              print(False)
          else:
              print(True)
          

          【讨论】:

          • @Jean-FrançoisFabre 不,它会检查整个事情的双打,然后测试结果,你是说更好的设计会在遇到双打时立即停止,如果是这样,我同意这样可以节省资源
          • 是的any(s.count(i) > 1 for i in s),这与我最初对all的评论完全相反
          • @Jean-FrançoisFabre 你还假设我读过你的 cmets,我没有,我只是看到并回答了,但我同意你的方法更有效,OP 应该使用它们,只是提供我的方法问题
          猜你喜欢
          • 2021-08-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-02-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多