【问题标题】:How to find a missing number from a list?如何从列表中找到丢失的号码?
【发布时间】:2013-12-21 11:05:44
【问题描述】:

如何以 Python 方式从排序列表中找到缺失的数字?

a=[1,2,3,4,5,7,8,9,10]

我遇到过这个post,但有没有更有效的方法来做到这一点?

【问题讨论】:

标签: python


【解决方案1】:
>>> a=[1,2,3,4,5,7,8,9,10]
>>> sum(xrange(a[0],a[-1]+1)) - sum(a)
6

或者(使用 AP 级数之和公式)

>>> a[-1]*(a[-1] + a[0]) / 2 - sum(a)
6

对于可能缺少多个数字的一​​般情况,您可以制定 O(n) 方法。

>>> a=[1,2,3,4,7,8,10]
>>> from itertools import imap, chain
>>> from operator import sub
>>> print list(chain.from_iterable((a[i] + d for d in xrange(1, diff))
                        for i, diff in enumerate(imap(sub, a[1:], a))
                        if diff > 1))
[5, 6, 9]

【讨论】:

  • 如果缺少 1、2、3 怎么办?
  • 问题是How to find missing number 而不是How to find amissing numbers
  • @thefourtheye:检查我的更新以了解具有多个空白的通用案例
  • 如果丢失的数字是最高或最低的,即。他的列表中缺少 1 或 10,则上述算法不起作用,但这是吹毛求疵。
  • @LasseV.Karlsen:那么我们可以争论这些数字是否真的丢失了,或者它们不应该在列表中。
【解决方案2】:

这应该可行:

a = [1, 3, 4, 5, 7, 8, 9, 10]
b = [x for x in range(a[0], a[-1] + 1)]
a = set(a)
print(list(a ^ set(b)))
>>> [2, 6]

【讨论】:

  • 优雅的解决方案,不涉及额外的模块(@Abhijit 提供的解决方案就是这种情况)。唯一的问题(不确定它是否存在!)是转换为集合。如果该列表已经包含唯一编号,我不确定应用 set() 转换时会对性能产生什么影响。遗憾的是,^ 运算符仅适用于集合,因此即使知道列表实际上是集合(尽管存储为列表),也需要进行转换。
  • @rbaleksandar 我相信该集合允许执行两个“列表”之间的对称差异。
【解决方案3】:
1 + 2 + 3 + ... + (n - 1) + n = (n) * (n + 1)/2

所以缺少的数字是:

(a[-1] * (a[-1] + 1))/2 - sum(a)

【讨论】:

  • 您的答案是正确的,但是鉴于您的第一句话,如果您在答案中实际使用了该事实,那就更有意义了,即删除第一部分并将其替换为产品...
  • 将其修改为与手头的问题相关。
【解决方案4】:
set(range(a[len(a)-1])[1:]) - set(a)

取所有数字的集合减去给定的集合。

【讨论】:

  • range(a[0],a[-1]+1) ?
  • @kelvinss 我在想他的数组总是从 1 开始,因为他问如果缺少 1,2,3 怎么办
  • 我意识到第二个参数中的+1 并不重要。但我认为range(1,a[-1]) 更清楚。
  • 我相信这是解决一般情况的最简洁的解决方案。提到的其他算法没有考虑差距。例如。 a=[1, 2, 4, 99]。你的方法可以适当地处理这个问题。
【解决方案5】:

还有一个itertools方式:

from itertools import count, izip

a=[1,2,3,4,5,7,8,9,10]
nums = (b for a, b in izip(a, count(a[0])) if a != b)
next(nums, None)
# 6

【讨论】:

    【解决方案6】:

    这将处理缺少第一个或最后一个数字的情况。

    >>> a=[1,2,3,4,5,7,8,9,10]
    >>> n = len(a) + 1
    >>> (n*(n+1)/2) - sum(a)
    6
    

    【讨论】:

      【解决方案7】:

      如果列表中有很多缺失的数字:

      >>> a=[1,2,3,4,5,7,8,10]
      >>> [(e1+1) for e1,e2 in zip(a, a[1:]) if e2-e1 != 1]
      [6, 9]
      

      【讨论】:

      • 你可能想说e2-e1 != 1
      • 如果a=[1,2,3,4,5,8,10]
      【解决方案8】:
      def find(arr):
              for x in range(0,len(arr) -1):
                      if arr[x+1] - arr[x] != 1:
                              print arr[x] + 1
      

      【讨论】:

        【解决方案9】:

        上述问题的简单解决方案,它还找到了多个缺失的元素。

        a = [1,2,3,4,5,8,9,10]
        missing_element = []
        for i in range(a[0], a[-1]+1):
            if i not in a:
                missing_element.append(i)
        
        print missing_element
        

        o/p: [6,7]

        【讨论】:

          【解决方案10】:

          这是在列表中查找缺失数字的简单逻辑。

          l=[-10,-5,2,4,5,9,20]
          s=l[0]
          e=l[-1]
          x=sorted(range(s,e+1))
          l_1=[]
          for i in x:
              if i not in l:
                  l_1.append(i)
          print(l_1)
          

          【讨论】:

          • 所有缺失的数字将被添加到 (l_1) 列表中。
          【解决方案11】:
          def findAllMissingNumbers(a):
             b = sorted(a)
             return list(set(range(b[0], b[-1])) - set(b))
          

          【讨论】:

            【解决方案12】:
            L=[-5,1,2,3,4,5,7,8,9,10,13,55]
            
            missing=[]
            
            for i in range(L[0],L[-1]):
                if i not in L:
                    missing.append(i)
            print(missing)
            

            【讨论】:

            • 嗨,乔,已经有 17 个其他答案,如果您可以在代码中添加解释以帮助我们了解它与其他答案的不同之处以及它如何解决其他答案没有的方式。谢谢!
            【解决方案13】:

            一种简单的列表理解方法,适用于多个(非连续)缺失数字。

            def find_missing(lst):
                """Create list of integers missing from lst."""
                return [lst[x] + 1 for x in range(len(lst) - 1) 
                        if lst[x] + 1 != lst[x + 1]]
            

            【讨论】:

              【解决方案14】:

              @Abhiji 提供了一个完美的解决方案。我想通过定义粒度值的选项来扩展他的答案。如果应该检查列表是否缺少value > 1,这可能是必要的:

              from itertools import imap, chain
              from operator import sub
              
              granularity = 3600
              data = [3600, 10800, 14400]
              
              print list(
                chain.from_iterable(
                  (data[i] + d for d in xrange(1, diff) if d % granularity == 0) 
                    for i, diff in enumerate(imap(sub, data[1:], data)) 
                      if diff > granularity
                )
              )
              

              上面的代码将产生以下输出:[7200]

              由于这段代码使用了很多嵌套函数,我还想提供一个快速的回溯参考,这有助于我理解代码:

              【讨论】:

                【解决方案15】:

                对于非常大的列表效率较低,但这是我的 Sum 公式版本:

                def missing_number_sum(arr):
                    return int((arr[-1]+1) * arr[-1]/2) - sum(arr)
                

                【讨论】:

                  【解决方案16】:

                  如果范围已知并给出列表,则以下方法将起作用。

                  a=[1,2,3,4,5,7,8,9,10]
                  missingValues = [i for i in range(1, 10+1) if i not in a]
                  print(missingValues)
                  
                  # o/p: [6] 
                  

                  【讨论】:

                    【解决方案17】:
                    set(range(1,a[-1])) | set(a)
                    

                    计算两个集合的并集。

                    【讨论】:

                      【解决方案18】:

                      我使用了索引位置。 这样我比较索引和值。

                      a=[0,1,2,3,4,5,7,8,9,10]
                      
                      for i in a:
                        print i==a.index(i)
                      

                      【讨论】:

                      • 没有给出预期的结果。
                      • 这根本不可扩展,如果数组数字远离索引,将无法工作。
                      猜你喜欢
                      • 2019-12-31
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2011-07-08
                      • 1970-01-01
                      • 2011-09-22
                      • 2012-09-06
                      相关资源
                      最近更新 更多