【问题标题】:Python sum of number in array, ignoring sections of specific numbers数组中数字的Python总和,忽略特定数字的部分
【发布时间】:2022-04-18 09:56:17
【问题描述】:

我是 Python 的新手,为了变得更好,我已经学习了多个教程。

我一直在解决一个难题并找到了解决方案。但感觉,作品很像新手。我认为我已经对其进行了定制以回答具体问题。

所以问题是:

SUMMER OF '69:返回数组中数字的总和,除了忽略以 6 开头并延伸到下一个 9 的数字部分(每个 6 后面至少有一个 9)。没有数字则返回 0。

summer_69([1, 3, 5]) --> 9
summer_69([4, 5, 6, 7, 8, 9]) --> 9
summer_69([2, 1, 6, 9, 11]) --> 14

我解决这个问题的代码是:

def summer_69(arr):
    list1 = arr
    summ = int()
    for i in range(0, len(arr)):
        if 6 in list1:
            listOfRange = range(list1.index(6), list1.index(9) + 1)
            for index in listOfRange:
                    print(listOfRange)
                    arr[index] = 0
            if 6 != arr[i]:
                summ += arr[i]
            else:
                continue
        else:
            summ += arr[i]
    return summ

这是一个非常基本的问题,我非常警觉我已经在与这样的事情作斗争。

【问题讨论】:

  • 这似乎是正确的(尽管效率很低)。你得到什么错误的输出?
  • del summer_69[summer_69.index(6):summer_69.index(9)+1] ;总和(summer_69)
  • @splash58 不考虑是否在第一个 6 之前出现 9
  • index6 = summer_69.index(6); index9 = summer_69[index6:].index(9);del summer_69[index6:index9+1] ;总和(summer_69)
  • @Ruzihm 是的,应该是summer_69[index6:index6+index9+1]

标签: python


【解决方案1】:

短 O(n) 解决方案使用迭代器和 in 运算符搜索(并由此跳至)每个 6 之后的 9:

def summer_69(lst):
    it = iter(lst)
    return sum(x for x in it
               if x != 6 or 9 not in it)

密度较低的版本

def summer_69(lst):
    it = iter(lst)
    total = 0
    for x in it:
        if x == 6:
            9 in it
        else:
            total += x
    return total

正确性检查(随机测试用例)和基准测试(使用[1] * 5000 + [6, 9] * 2500)以及接受答案的解决方案(需要 O(n2支持>)):

30 out of 30 tests correct

303045 us  303714 us  304335 us  306007 us  309986 us  summer_69_Accepted
   444 us     446 us     464 us     478 us     527 us  summer_69_Kelly1
   442 us     448 us     453 us     465 us     500 us  summer_69_Kelly2

代码(Try it online!):

from timeit import repeat

def summer_69_Accepted(lst):
    copyoflist = lst[:] # makes shallow copy of list
    while True:
        if 6 not in copyoflist:
            return sum(copyoflist)

        indexof6 = copyoflist.index(6)
        indexof9 = copyoflist.index(9, indexof6+1) # begin search for 9 after 6
        del copyoflist[indexof6:indexof9+1] 

def summer_69_Kelly1(lst):
    it = iter(lst)
    return sum(x for x in it
               if x != 6 or 9 not in it)

def summer_69_Kelly2(lst):
    it = iter(lst)
    total = 0
    for x in it:
        if x == 6:
            9 in it
        else:
            total += x
    return total

funcs = summer_69_Accepted, summer_69_Kelly1, summer_69_Kelly2

from random import randrange, choices

def testcase():
    def others():
        return choices([0, 1, 2, 3, 4, 5, 7, 8], k=randrange(10))
    lst = others()
    for _ in range(10):
        lst += [6, *others(), 9, *others()]
    return lst

tests = correct = 0
for _ in range(10):
    lst = testcase()
    expect = funcs[0](lst.copy())
    for func in funcs:
        result = func(lst.copy())
        correct += result == expect
        tests += 1
print(correct, 'out of', tests, 'tests correct')
print()

lst = [1] * 5000 + [6, 9] * 2500
for func in funcs:
    times = repeat(lambda: func(lst), number=1)
    print(*('%6d us ' % (t * 1e6) for t in sorted(times)), func.__name__)

【讨论】:

  • 很大的改进,我会删除我的劣质答案,但不能删除已接受的答案:(
  • @Ruzihm 不希望你这样做,会让我看起来像一个疯狂的人在想象事情:-)
【解决方案2】:

这是一个版本,它使用了更可重用的 Pythonic 习语、生成器函数,并且更紧凑(以额外比较为代价):

def yield_non_summer(series):
  in_summer = False
  def stateful_summer_predicate(v):
    nonlocal in_summer
    if in_summer and v == 9:
      in_summer = False
      return True  # 9 is still in summer
    elif not in_summer and v == 6:
      in_summer = True
    return in_summer
  return (v for v in series if not stateful_summer_predicate(v))

def summer_69(series):
  return sum(yield_non_summer(series))

或者,用更少的行:

def yield_non_summer(series):
  in_summer = False
  def stateful_summer_predicate(v):
    nonlocal in_summer
    in_summer = (in_summer or v == 6) and v != 9
    return in_summer
  return (v for v in series if not stateful_summer_predicate(v))

def summer_69(series):
  return sum(yield_non_summer(series))

【讨论】:

    【解决方案3】:
    def summer_69(arr):
    sum = 0
    Flag = False
    if 6 not in arr:
        for num in arr:
            sum = sum + num
        return sum
    else:
        for num in arr:
            if num != 6 and Flag == False:
                sum = sum + num                
            elif num == 6:
                Flag = True
                continue
            elif Flag == True and num != 9:
                continue
            elif num == 9:
                Flag = False
        return sum
    

    【讨论】:

    • 这看起来不错,但可以将 Flag 重命名为 inside_skip,以提高可读性(并符合 PEP 8)。
    • 你也可以写成'sum += num'。并且建议使用“if Flag is False”(而不是比较)。
    【解决方案4】:

    一种简单的方法是制作一个过滤器并对结果求和。

    代码

    def filter_substring(seq, start, end):
        """Yield values outside a given substring."""
        release = True
    
        for x in seq:
    
            if x == start:
                release = False
            elif x == end:
                release = True
            elif release:
                yield x
    
    
    def summer(seq):
        """Return the sum of certain values."""
        return sum(filter_substring(seq, 6, 9))
    

    演示

    assert 0 == summer([])
    assert 6 == summer([1, 2, 3])
    assert 6 == summer([1, 2, 3, 6, 8, 7, 9])
    assert 9 == summer([1, 3, 5])
    assert 8 == summer([3, 5, 6, 7, 8, 9])
    assert 15 == summer([2, 1, 6, 9, 12])
    assert 16 == summer([2, 1, 6, 9, 1, 6, 6, 120, 9, 9, 12])
    
    

    详情

    filter_substring()+

    这是一个生成器函数。它迭代输入序列并且仅在条件合适时才产生一个值,即当release 保持True 时。

    >>> list(filter_substring("abcde", "c", "d"))
    ['a', 'b', 'e']
    >>> list(filter_substring([0, 1, 2, 3, 10], 1, 3))
    [0, 10]
    

    summer()

    在这里,我们简单地总结 filter_range() 产生的任何东西。

    +注意:substring 是连续的subsequence;这可能包含也可能不包含 Python 中的字符串。

    【讨论】:

      【解决方案5】:

      将使用索引:

      def summer_69(arr):
          y = []
          for x in arr:
              if 6 in arr:
                  a = arr.index(6)
                  b = arr.index(9)
                  del arr[a:b+1]
                  y = arr
              elif arr == []:
                  return "0"
              else:
                  return sum(arr)
          return sum(y)
      print(summer_69([]))                                                          #0
      print(summer_69([1, 3, 5]))                                                   #9
      print(summer_69([4, 5, 6, 7, 8, 9]))                                          #9
      print(summer_69([2, 1, 6, 9, 11]))                                            #14
      print(summer_69([2, 1, 6, 9, 6, 11, 25, 36, 11, 9, 4, 6, 4, 6, 3, 9, 15]))    #22
      

      【讨论】:

      • 您好!虽然此代码可能会解决问题,但包括解释如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请编辑您的答案以添加解释并说明适用的限制和假设。
      • "elif arr == []: return "0"" 这一行似乎是多余的,而“0”是错误的——它必须是一个数字,而不是一个字符串。但是感谢您的回答,欢迎来到 Stack Overflow!
      • 但是,必须在文档字符串中明确说明此函数更改了原始数组。与任意(可能很重要)数据一起使用是不安全的。
      • 您好雅罗斯拉夫,感谢您的反馈。在没有数字的情况下,我没有发现函数必须返回数字而不是字符串的任何要求。
      • 嗨,亚历克斯。很高兴这有用!我只是认为总是返回一种类型的结果更可靠:) 否则这个函数的用户很容易在他们的代码中出现错误或不必要的并发症。
      【解决方案6】:

      这是我的做法,作为第一次剪辑:

      def summer_69(series):
        in_summer = False
        cur_sum = 0
        for v in series:
          if in_summer:
            if v == 9:
              in_summer = False
          else:
            if v == 6:
              in_summer = True
            else:
              cur_sum += v
        return cur_sum
      

      【讨论】:

        【解决方案7】:

        类似这样的:

        def summer_69(lst):
          """Return the sum of the numbers in the array, 
             except ignore sections of numbers starting with a 6 and extending to the next 9 
             (every 6 will be followed by at least one 9). Return 0 for no numbers
          """
          if not lst:
            return 0
          else:
            _sum = 0
            active = True
            for x in lst:
              if active: 
                if x != 6:
                  _sum += x
                else:
                  active = False
              else:
                if x == 9:
                  active = True
            return _sum
        
        print(summer_69([1, 3, 5]))
        print(summer_69([4, 5, 6, 7, 8, 9]))
        print(summer_69([2, 1, 6, 9, 11]))
        

        输出

        9
        9
        14
        

        【讨论】:

          【解决方案8】:
          def summer_69(arr):
              if 6 in arr:
                  c=arr[arr.index(6):arr.index(9)+1]
                  for i in c:
                      arr.remove(i)
                  print(arr)
                  return sum(arr)
              else:
                  return sum(arr)
          
          summer_69([1,2,3,4,5,6,7,8,9,10,11,12])
          

          【讨论】:

            【解决方案9】:

            这将起作用:

            def summer_69(arr):
                total = 0
                add = True
                for num in arr:
                    while add:
                        if num != 6:
                            total += num
                            break
                        else:
                            add = False
                    while not add:
                        if num != 9:
                            break
                        else:
                            add = True
                            break
                return total
            

            【讨论】:

            【解决方案10】:
            def summer_69(arr):
                a = 0
                for nums in arr: 
                    if nums == 6:
                        for items in arr[arr.index(6):]:
                            a = a+ items
                            if items == 9:
                                break
                return sum(arr)-a
            

            【讨论】:

            • 您好!虽然这段代码可以解决问题,including an explanation 解决问题的方式和原因确实有助于提高帖子的质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。
            【解决方案11】:
            def summer_69(arr):
                    x = arr.count(6)
                    y = arr.count(9)
                    # to decide number of iteration required for loop
                    z = min(x,y)
                    k = 0
                    while k < (z) :
                        m = arr.index(6)
                        n = arr.index(9)
                        del arr[m:(n+1)]
                        k = k + 1
                    print(arr)
                    return sum(arr)
            

            【讨论】:

            • 你好,欢迎来到SO!,包括一个简短的解释有利于OP理解你的解决方案,如果需要请记得给出解释和参考。
            【解决方案12】:

            这将适用于 summer_69 问题以及过滤子字符串

            def filter_substring(seq, start, end):
            flag = False
            for char in seq:
                if char == start:
                    flag = True
                    continue
                elif flag:
                    if char == end:
                        flag = False 
                    else:
                        continue
                else:
                    yield char
            
            def summer_69(seq, start, end):
                return sum(filter_substring(seq, start, end))
            
            def print_substring(string, start, end):
                return list(filter_substring(string, start, end))
            

            示例 ::

            seq = [4, 5, 9, 6, 2, 9, 5, 6, 1, 9, 2]
            print(summer_69(seq, start=6, end=9))
            
            
            string = "abcdef"
            print(print_substring(string, start='c', end='e'))
            

            【讨论】:

              【解决方案13】:

              如果您是新手,这可能是最好的答案。我已经尽可能地简化了它。你只需要知道枚举、函数、for循环、元组解包、if/else语句和break函数。所以让我们直接回答吧。

              def myfunc(a):
              mylist=[]
              sum1 = 0
              for b,c in enumerate(a):
                  if c==6:
                     for d in  a[:b]:
                         mylist.append(d)
              for e,f in enumerate(a):
                  if f==9:
                     for j in a[e+1:]:
                         mylist.append(j)
              for y in a:
                  if y==6:
                    break
                  else:
                     mylist.append(y)
              for k in mylist:
                  sum1 = sum1+k
              print(sum1)
              

              myfunc([1,3,5])

              【讨论】:

              • 这确实存在格式问题,以及代码理解问题。考虑添加一些 cmets 以及正确的格式。使用 {} 发布代码 sn-ps。
              【解决方案14】:

              对于那些感兴趣的人,这是我对这个问题的解决方案:

              def summer_69(arr):
                  skate = arr
                  guitar = []
                  for i in range(len(arr)):
                      if 6 in arr:
                          guitar = skate[skate.index(6):skate.index(9)+1]
                          return abs(sum(skate) - sum(guitar))
                      else:
                          return sum(skate)
              

              【讨论】:

                【解决方案15】:

                替换

                list1.index(9)+1 
                by 
                list1.index(9,list1.index(6)+1)+1
                

                在第 6 行。 这将在 6 之后开始搜索 9。

                【讨论】:

                • 请在您的回复中包含代码格式并解释您的解决方案
                【解决方案16】:

                这是取自 Udemy 课程。

                这是官方的回答。 . .

                def summer_69(arr):
                total = 0
                add = True
                for num in arr:
                    while add:
                        if num != 6:
                            total += num
                            break
                        else:
                            add = False
                    while not add:
                        if num != 9:
                            break
                        else:
                            add = True
                            break
                return total
                

                Jose Periera 在 Python 的“从零到英雄”课程中有此内容。

                【讨论】:

                  【解决方案17】:

                  我自己的特殊方法是这样。 . .

                  def summer_69(arr):
                  
                  #first find out if 6 or 9 are in the list
                  
                  if 6 in arr and 9 in arr:
                  
                  #Then create a variable that stores the index location of the number 6 
                  #and the number 9
                  
                          sixer = arr.index(6)
                          niner = arr.index(9)
                  
                  #now return the sum of the array minus the sum of the values between 
                  #index of 6 and index of 9 inclusive (hence the plus 1)
                  #This way will ignore the case of a 9 appearring before a 6 too.
                  
                          return sum(arr) - sum(arr[sixer:niner+1])
                  
                  #Otherwise just return the sum of the array.
                  
                  else:
                      return sum(arr)
                  

                  很高兴在这里接受批评。我自己正在学习 Python,并且正在攻读计算机科学硕士学位,并希望尽快申请该领域的工作,所以你们的 cmets 会帮助我:)

                  【讨论】:

                    【解决方案18】:

                    我的方法是将整个列表和列表中我们想要忽略的部分相加,然后在最后减去它们。

                    def summer_69(arr):
                    result=0
                    reduction =0
                    for i in range(0,len(arr)):
                        result+=arr[i]
                        if arr[i] == 6:
                            temp = arr[arr.index(6):arr.index(9)+1]
                            reduction = sum(temp)
                    return result - reduction
                    

                    【讨论】:

                      【解决方案19】:
                      def summer69(a):
                          for z in a:
                              if z==6 and 9 in a:
                                 x=a.index(6)
                                 y=a.index(9)
                                 del a[x:y+1]
                                 t= sum(a)
                              else:
                                 t=sum(a)
                          return t
                      

                      总是喜欢简短、清晰和易于理解的解决方案。

                      【讨论】:

                        【解决方案20】:
                        def summer_69(arr):
                        if 9 in arr :
                            sum = 0 
                            y = arr.index(9)
                            for i , l in enumerate(arr):
                                if l == 6:
                                    del arr[i:y+1]
                            for i in range(len(arr)):
                                sum = sum + arr[i]
                            return sum
                        elif 9 not in arr:
                            sum = 0
                            for i in range(len(arr)):
                                sum = sum + arr[i]
                            return sum 
                        

                        【讨论】:

                          猜你喜欢
                          • 2019-11-14
                          • 2020-09-24
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2021-01-25
                          • 1970-01-01
                          相关资源
                          最近更新 更多