Python-计数符号更改
我有一个从左到右阅读的数字列表。每当我在阅读序列时遇到符号变化时,我都想数一数Python-计数符号更改,python,list,Python,List,我有一个从左到右阅读的数字列表。每当我在阅读序列时遇到符号变化时,我都想数一数 X = [-3,2,7,-4,1,-1,1,6,-1,0,-2,1] X = [-, +, +, -, +, -, +, +, -, -,-,+] 因此,在这个列表中有8个符号变化 当项目[0](在本例中为-3)为负数时,视为符号更改。此外,列表中的任何0都被视为[-] 任何帮助都将不胜感激 您可以使用来计算正数和非正数组: >>> x = [-3,2,7,-4,1,-1,1,6,-1,0,-2
X = [-3,2,7,-4,1,-1,1,6,-1,0,-2,1]
X = [-, +, +, -, +, -, +, +, -, -,-,+]
因此,在这个列表中有8个符号变化
当项目[0]
(在本例中为-3)为负数时,视为符号更改。此外,列表中的任何0都被视为[-]
任何帮助都将不胜感激 您可以使用来计算正数和非正数组:
>>> x = [-3,2,7,-4,1,-1,1,6,-1,0,-2,1]
>>> import itertools
>>> len(list(itertools.groupby(x, lambda x: x > 0)))
结果:
8
在您的问题中,您声明您想要:
- 计算更改,而不是组
- 如果第一个元素不是正数,则计算额外的更改
>>> len(list(itertools.groupby(x, lambda x: x > 0))) - (x[0] > 0)
>>> len(list(itertools.groupby(itertools.chain([1], x), lambda x: x > 0))) - 1
或者在进行分组之前,在输入前加上一个正数,然后从结果中减去1:
>>> len(list(itertools.groupby(x, lambda x: x > 0))) - (x[0] > 0)
>>> len(list(itertools.groupby(itertools.chain([1], x), lambda x: x > 0))) - 1
注意输入列表是否可能为空-前一个解决方案将引发异常
X = [-3,2,7,-4,1,-1,1,6,-1,0,-2,1]
last_sign = 1
sign_changes = 0
for x in X:
if x == 0:
sign = -1
else:
sign = x / abs(x)
if sign == -last_sign:
sign_changes = sign_changes + 1
last_sign = sign
print sign_changes
->七,
对于您的额外要求,即列表开头的负数应视为另一个更改,只需在列表中添加正数即可
如果你处理大的列表,考虑使用生成器。(izip,tee,…)
这是一个使用fold的解决方案,让您从中找到乐趣:def lolwut((x,c), y):
return (y, c+(x^y))
print reduce( lolwut ,(x > 0 for x in X), (True,0)) # 8
print reduce( lolwut ,(x > 0 for x in X), (False,0)) # 7
如果您还没有被说服阅读itertools文档:
def pairs(iterable):
'iter -> (iter0, iter1), (iter1, iter2), (iter3, iter4), ...'
from itertools import izip, tee
first, second = tee(iterable)
second.next()
return izip(first, second)
def sign_changes(l):
result = 0
if l and l[0]<=0: result += 1
result += sum(1 for a,b in pairs(l) if b*a<=0 and (a!=0 or b!=0))
return result
def对(iterable):
“iter->(iter0,iter1),(iter1,iter2),(iter3,iter4),”
从itertools导入izip,tee
第一,第二=T形三通(可调)
二,下一步()
返回izip(第一,第二)
def符号更改(l):
结果=0
如果l和l[0]表示整数,如果a和b的符号不同,则(a^b)<0
def countSignChanges(seq):
# make sure 0's are treated as negative
seq = [-1 if not x else x for x in seq]
# zip with leading 1, so that opening negative value is
# treated as sign change
return sum((a^b)<0 for a,b in zip([1]+seq, seq))
X = [-3,2,7,-4,1,-1,1,6,-1,0,-2,1]
print countSignChanges(X)
def countSignChanges(seq):
#确保0被视为负值
seq=[-1如果不是x,则x表示seq中的x]
#使用前导1进行压缩,以便打开负值为
#视为符号变化
返回和((a^b)这里有一种不使用循环的方法…对于大数据来说应该快得多;)(但是,由于numpy等,对于小列表来说效率不高-而且由于明显的原因,numpy数组要比列表好得多-您甚至可以放弃转换…)
返回8
如果两个布尔值不同(从+到-),且速度相当快,则Xor返回true。代码有一个问题:如果某个值从正号精确到0,它将被视为交叉。这正是您在问题中提出的问题,因为您将0表示为“-” Input=[-1,2,3,-4,5,-6,7,8,-9,10,-11,12]
Input = [-1, 2, 3, -4, 5, -6, 7, 8, -9, 10, -11, 12]
for i in range(len(Input)):
if(Input[i]<1):
Input[i]=0
else:
Input[i]=1
print(Input) #[0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1]
count=0
check=Input[0]
for i in range(len(Input)-1):
if check != Input[i + 1]:
count+=1
check=Input[i+1]
print(count) #9
对于范围内的i(len(输入)):
if(输入[i]+1,因为我写了同样的东西,除了它看起来像len(list(itertools.groupby(x>0代表x中x)))
代表x中x
严重吗?这比b中a的更糟糕,如果它能帮助任何人回答问题,这里有一个哈斯克尔解决方案:signChanges xs=sum$zipWith(\xy->如果(x>0)=(y>0)那么0代表其他1)(1:xs)xs
这里有一个链接供寻找的人使用。可能打印count-1以匹配op预期答案列表中有9个符号更改,因此9是正确答案。