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配列)に符号が交互に付いている数字が含まれているかどうかを知るための素敵な方法がありますか?言い換えれば、交互の符号を検出する
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
OK、SO "related"機能のおかげです。私はあなたがすべてのも、メンバーを確認することができ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
であることは否定的であり、すべての奇数メンバーは、スライスを取ることによって、肯定的です1つ目の項目から始まり、または1つ目の項目から始まります。両方の可能性をカバーするために逆もテストしてください。
はそう:decimalモジュールとis_signed方法を使用して
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])))
なぜ 'x> = 0'ではなく' x> 0'ですか? –
それは本当に "交互符号"を定義する方法に依存します - 私は非負とゼロをグループ化するかどうかに応じてどちらかの方法を見ることができます(つまり、 "符号"を一般に負の符号で書くかどうかを判断する)独自のサインレスカテゴリ。 (そのような場合でも、[1,0,1,0]は「交互の兆候」であると主張する可能性もあります) – Brian
は:
は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)
私が好きなペアワイズは:iterable
にはゼロが存在しない場合
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))
これも動作します:
以下のような何かについてdef is_alternating_signs(iterable):
return all((x < 0) == (0 < y) for x, y in pairwise(iterable))
か...
def is_alternating_signs(aList):
return all((aList[i]^aList[i-1])<0 for i in range(1,len(aList)))
何度とテスト、それをループでわずかストレートフォワードソリューションについてはどうですか?他の多くのソリューションの多くがリストを何度もループするので、おそらく最も速いです。
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つ未満の場合、意図した動作が何であるかはっきりしていないことに注意してください。
がここでおそらく他の提案のいくつかよりも効率が低い私のワンライナー、です:
def is_alternating_signs(lst):
return all(x * y < 0 for x, y in zip(lst, lst[1:]))
また、これは '[0,1,0,1,0]'は 'true'をです。私の提案: 'numpy.all(numpy.abs(numpy.diff(numpy.sign(a)))== 2)' –