【问题标题】:Detect alternating signs检测交替标志
【发布时间】:2011-06-23 08:49:38
【问题描述】:

有没有一种简单的方法来判断 python 列表(或 numpy 数组)是否包含带有交替符号的数字?换句话说:

is_alternating_signs([1, -1, 1, -1, 1]) == True
is_alternating_signs([-1, 1, -1, 1, -1]) == True
is_alternating_signs([1, -1, 1, -1, -1]) == False

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    好的,感谢“相关”功能。我找到了this question 并采纳了ianalis 的答案和lazyr 的评论

    def is_alternating_signs(a):
        return numpy.all(numpy.abs(numpy.diff(numpy.sign(a))) == 2)
    
    
    
    print is_alternating_signs([1, -1, 1, -1, 1]) 
    print is_alternating_signs([-1, 1, -1, 1, -1]) 
    print is_alternating_signs([1, -1, 1, -1, -1]) 
    

    输出是

    True
    True
    False
    

    【讨论】:

    • 这也是True for [0,1,0,1,0]。我的建议:numpy.all(numpy.abs(numpy.diff(numpy.sign(a))) == 2)
    【解决方案2】:

    您可以检查每个偶数成员是否为负数,每个奇数成员是否为正数,方法是从开头或从第一个位置开始每隔一个项目取一片。还要测试相反的情况以涵盖这两种可能性。

    所以:

    def is_alternating_signs(l):
        return ( (all(x<0 for x in l[::2]) and all(x>=0 for x in l[1::2])) or
                 (all(x>=0 for x in l[::2]) and all(x<0 for x in l[1::2])))
    

    【讨论】:

    • 这真的取决于我们如何定义“交替符号” - 我可以看到任何一种方式,这取决于您是否将零与非负数组合在一起(即,将“符号”作为我们通常是否会用负数来写它符号)或将其放在自己的无符号类别中。 (尽管在这种情况下,您甚至可以争辩说 [1,0,1,0] 是“交替符号”)
    【解决方案3】:

    使用decimal 模块和is_signed 方法:

    from decimal import Decimal
    
    a = [1, -1, 1, -1, 1]
    b = [-1, 1, -1, 1, -1]
    c = [1, -1, 1, -1, -1]
    
    def is_alternating_signs(values):
        lVals = [Decimal(val).is_signed() for val in values]
        prevVal = lVals.pop(0)
        for val in lVals:
            if prevVal == val:
                return False
            prevVal = val
        return True
    
    is_alternating_signs(a)
    is_alternating_signs(b)
    is_alternating_signs(c)
    

    【讨论】:

      【解决方案4】:

      我喜欢成对的:

      from itertools import izip, tee
      
      def pairwise(iterable):
          a, b = tee(iterable)
          next(b)
          return izip(a, b)
      
      def is_alternating_signs(iterable):
          return all(x < 0 < y or x > 0 > y for x, y in pairwise(iterable))
      

      如果iterable 中没有零,这也​​可以:

      def is_alternating_signs(iterable):
          return all((x < 0) == (0 < y) for x, y in pairwise(iterable))
      

      【讨论】:

        【解决方案5】:

        怎么样...

        def is_alternating_signs(aList):
            return all( (aList[i]^aList[i-1])<0 for i in range(1,len(aList)) )
        

        【讨论】:

          【解决方案6】:

          循环遍历一次并进行测试的直接解决方案怎么样?也很可能是最快的,因为许多其他解决方案会多次循环遍历列表。

          def signs_are_alternating(numbers):
              """Return True if numbers in given list have alternating signs, False
              otherwise. If given list has less than 2 elements, return False.
          
              >>> signs_are_alternating([1, -1, 1, -1, 1])
              True
              >>> signs_are_alternating([-1, 1, -1, 1, -1])
              True
              >>> signs_are_alternating([1, -1, 1, -1, -1])
              False
          
              """
              if len(numbers) < 2:
                  return False
              previous_positive = (numbers[0] < 0)  # Pretend it starts alternating
              for number in numbers:
                  this_positive = (number >= 0)
                  if previous_positive == this_positive:
                      return False
                  previous_positive = this_positive
              return True
          

          请注意,如果输入列表的元素少于 2 个,我不太确定预期的行为是什么。

          【讨论】:

            【解决方案7】:

            这是我的单线,它可能比其他一些建议效率低:

            def is_alternating_signs(lst):
                return all(x * y < 0 for x, y in zip(lst, lst[1:]))
            

            【讨论】:

              猜你喜欢
              • 2023-01-17
              • 2015-12-24
              • 1970-01-01
              • 2019-10-11
              • 1970-01-01
              • 2012-08-01
              • 2018-12-19
              • 2011-02-12
              • 2021-10-03
              相关资源
              最近更新 更多