给出如下数据列表:
input = [1,1,1,1,5,5,3,3,3,3,3,3,2,2,2,5,5]
我想创建一个能够偏移一定数量步骤列表的算法。例如,如果offset = -1:
def offsetFunc(inputList, offsetList):
#make something
return output
其中:
output = [0,0,0,0,1,1,5,5,5,5,5,5,3,3,3,2,2]
重要提示:列表中的元素是浮点数,它们没有任何进展。所以我实际上需要转移它们,我不能使用任何解决方法来获得结果。
所以基本上,算法应该用0替换第一组值(基本上是4“1”)然后它应该:
我粗略描述上述算法的方式就是我如何做到这一点。然而,我是Python的新手(甚至是普通编程的初学者),我已经及时发现Python有很多内置函数可以使算法减少繁重和迭代。有没有人有任何建议可以更好地开发脚本来完成这种工作?这是我到目前为止编写的代码(假设静态偏移量为-1):
input = [1,1,1,1,5,5,3,3,3,3,3,3,2,2,2,5,5]
output = []
PrevVal = 0
NextVal = input[0]
i = 0
while input[i] == NextVal:
output.append(PrevVal)
i += 1
while i < len(input):
PrevVal = NextVal
NextVal = input[i]
while input[i] == NextVal:
output.append(PrevVal)
i += 1
if i >= len(input):
break
print output
提前感谢您的帮助!
更好的描述 我的列表将始终由值的“集合”组成。它们通常是浮点数,它们采用的值如下面这个简短的例子:
Sample = [1.236,1.236,1.236,1.236,1.863,1.863,1.863,1.863,1.863,1.863]
在这个例子中,第一个集合(值为“1.236”的集合)是长4而第二个集合是长6.当offset = -1时,我希望得到的输出是:< / p>
所以基本上,这个“偏移”函数创建的列表具有相同的“结构”(长度范围),但值延迟了“偏移”次。
我希望现在很清楚,不幸的是问题本身对我来说仍然有点傻(加上我甚至不会说英语:)) 请不要犹豫,提出任何其他信息来完成问题并使其更清晰。
答案 0 :(得分:6)
这个怎么样:
def generateOutput(input, value=0, offset=-1):
values = []
for i in range(len(input)):
if i < 1 or input[i] == input[i-1]:
yield value
else: # value change in input detected
values.append(input[i-1])
if len(values) >= -offset:
value = values.pop(0)
yield value
input = [1,1,1,1,5,5,3,3,3,3,3,3,2,2,2,5,5]
print list(generateOutput(input))
它会打印出来:
[0, 0, 0, 0, 1, 1, 5, 5, 5, 5, 5, 5, 3, 3, 3, 2, 2]
如果你只想迭代,你甚至不需要构建列表。然后使用for i in generateOutput(input): …
。
对于其他偏移,请使用:
print list(generateOutput(input, 0, -2))
打印:
[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 5, 5, 5, 3, 3]
答案 1 :(得分:2)
使用deque
作为队列,并使用maxlen定义移位长度。只持有唯一值。最后推送inn值,在队列开始时推出旧值,当达到移位长度时。
from collections import deque
def shift(it, shift=1):
q = deque(maxlen=shift+1)
q.append(0)
for i in it:
if q[-1] != i:
q.append(i)
yield q[0]
Sample = [1.236,1.236,1.236,1.236,1.863,1.863,1.863,1.863,1.863,1.863]
print list(shift(Sample))
#[0, 0, 0, 0, 1.236, 1.236, 1.236, 1.236, 1.236, 1.236]
答案 2 :(得分:2)
我的尝试:
#Input
input = [1,1,1,1,5,5,3,3,3,3,3,3,2,2,2,5,5]
shift = -1
#Build service structures: for each 'set of data' store its length and its value
set_lengths = []
set_values = []
prev_value = None
set_length = 0
for value in input:
if prev_value is not None and value != prev_value:
set_lengths.append(set_length)
set_values.append(prev_value)
set_length = 0
set_length += 1
prev_value = value
else:
set_lengths.append(set_length)
set_values.append(prev_value)
#Output the result, shifting the values
output = []
for i, l in enumerate(set_lengths):
j = i + shift
if j < 0:
output += [0] * l
else:
output += [set_values[j]] * l
print input
print output
给出:
[1, 1, 1, 1, 5, 5, 3, 3, 3, 3, 3, 3, 2, 2, 2, 5, 5]
[0, 0, 0, 0, 1, 1, 5, 5, 5, 5, 5, 5, 3, 3, 3, 2, 2]
答案 3 :(得分:1)
def x(list, offset):
return [el + offset for el in list]
答案 4 :(得分:1)
与我的第一个答案完全不同的是:
import itertools
首先分析输入:
values, amounts = zip(*((n, len(list(g))) for n, g in itertools.groupby(input)))
我们现在有(1, 5, 3, 2, 5)
和(4, 2, 6, 3, 2)
。现在应用偏移量:
values = (0,) * (-offset) + values # nevermind that it is longer now.
再次合成:
output = sum([ [v] * a for v, a in zip(values, amounts) ], [])
这种方式更优雅,更难理解,可能比我的其他答案更昂贵,但我不想把它藏起来。