根据值和规则拆分整数列表的更好方法
Better way to split list of integers based on values and rules
目标是根据这些规则根据每个元素的邻居拆分整数列表:
(current/focal值小于或等于前一个)和(当前值等于下一个),即prev_value >= focal_value == next_value
(当前值小于上一个)和(当前值小于下一个),即prev_value > focal_value < next_value
为了说明,给定 x
产生 y
:
x = (1, 4, 2, 1, 4, 2, 4, 1, 4, 1, 4, 4, 3)
y = [[1, 4, 2], [1, 4], [2, 4], [1, 4], [1, 4, 4, 3]]
assert func(x) == y
我试过:
def per_window(sequence, n=1):
"""
From
>>> list(per_window([1,2,3,4], n=2))
[(1, 2), (2, 3), (3, 4)]
>>> list(per_window([1,2,3,4], n=3))
[(1, 2, 3), (2, 3, 4)]
"""
start, stop = 0, n
seq = list(sequence)
while stop <= len(seq):
yield tuple(seq[start:stop])
start += 1
stop += 1
def func(x):
result = []
sub_result = [x[0]]
for prev_value, focal_value, next_value in per_window(x, 3):
# These if and elif cases trigger syllable break.
if prev_value >= focal_value == next_value:
sub_result.append(focal_value)
result.append(sub_result)
sub_result = []
elif prev_value > focal_value < next_value:
result.append(sub_result)
sub_result = []
sub_result.append(focal_value)
else: # no break
sub_result.append(focal_value)
sub_result.append(next_value)
result.append(sub_result)
return result
x = (1, 4, 2, 1, 4, 2, 4, 1, 4, 1, 4, 4, 3)
y = [[1, 4, 2], [1, 4], [2, 4], [1, 4], [1, 4, 4, 3]]
assert func(x) == y
但我的问题是:
如果我们仔细观察 if 和 elif "cases",看起来第一个 if 永远不会被捕获,因为第二个 if 会先到达。那正确吗?第一个 if
案例将启动的示例是什么?
有没有更好的方法达到同样的按规则拆分子列表的目的?
最后两个追加需要存在于per_window
的循环之外,这些扼杀者叫什么?有没有办法不这样做就循环?
对于你的例子,第一个 if 永远不会被触发。但它将与此示例数据一起使用:
x = (5 ,4, 4, 2)
y = [[5, 4], [4, 2]]
更好是相当主观的。但是不使用 windows 也可以达到相同的目标,只需移动值
def func2(x):
x = iter(x)
try:
prev_value = next(x)
focal_value = next(x)
except StopIteration:
return [list(x)]
sub_result = [prev_value]
result = [sub_result]
for next_value in x:
if prev_value >= focal_value == next_value:
sub_result.append(focal_value)
sub_result = []
result.append(sub_result)
elif prev_value > focal_value < next_value:
sub_result = [focal_value]
result.append(sub_result)
else:
sub_result.append(focal_value)
prev_value, focal_value = focal_value, next_value
sub_result.append(focal_value)
return result
timeit
说快了两倍
一旦你持有循环中的最后一个值,你将不得不在循环后对其进行特殊处理。但是我的代码表明可以在循环内附加 sub_result
列表。
目标是根据这些规则根据每个元素的邻居拆分整数列表:
(current/focal值小于或等于前一个)和(当前值等于下一个),即
prev_value >= focal_value == next_value
(当前值小于上一个)和(当前值小于下一个),即
prev_value > focal_value < next_value
为了说明,给定 x
产生 y
:
x = (1, 4, 2, 1, 4, 2, 4, 1, 4, 1, 4, 4, 3)
y = [[1, 4, 2], [1, 4], [2, 4], [1, 4], [1, 4, 4, 3]]
assert func(x) == y
我试过:
def per_window(sequence, n=1):
"""
From
>>> list(per_window([1,2,3,4], n=2))
[(1, 2), (2, 3), (3, 4)]
>>> list(per_window([1,2,3,4], n=3))
[(1, 2, 3), (2, 3, 4)]
"""
start, stop = 0, n
seq = list(sequence)
while stop <= len(seq):
yield tuple(seq[start:stop])
start += 1
stop += 1
def func(x):
result = []
sub_result = [x[0]]
for prev_value, focal_value, next_value in per_window(x, 3):
# These if and elif cases trigger syllable break.
if prev_value >= focal_value == next_value:
sub_result.append(focal_value)
result.append(sub_result)
sub_result = []
elif prev_value > focal_value < next_value:
result.append(sub_result)
sub_result = []
sub_result.append(focal_value)
else: # no break
sub_result.append(focal_value)
sub_result.append(next_value)
result.append(sub_result)
return result
x = (1, 4, 2, 1, 4, 2, 4, 1, 4, 1, 4, 4, 3)
y = [[1, 4, 2], [1, 4], [2, 4], [1, 4], [1, 4, 4, 3]]
assert func(x) == y
但我的问题是:
如果我们仔细观察 if 和 elif "cases",看起来第一个 if 永远不会被捕获,因为第二个 if 会先到达。那正确吗?第一个
if
案例将启动的示例是什么?有没有更好的方法达到同样的按规则拆分子列表的目的?
最后两个追加需要存在于
per_window
的循环之外,这些扼杀者叫什么?有没有办法不这样做就循环?
对于你的例子,第一个 if 永远不会被触发。但它将与此示例数据一起使用:
x = (5 ,4, 4, 2) y = [[5, 4], [4, 2]]
更好是相当主观的。但是不使用 windows 也可以达到相同的目标,只需移动值
def func2(x): x = iter(x) try: prev_value = next(x) focal_value = next(x) except StopIteration: return [list(x)] sub_result = [prev_value] result = [sub_result] for next_value in x: if prev_value >= focal_value == next_value: sub_result.append(focal_value) sub_result = [] result.append(sub_result) elif prev_value > focal_value < next_value: sub_result = [focal_value] result.append(sub_result) else: sub_result.append(focal_value) prev_value, focal_value = focal_value, next_value sub_result.append(focal_value) return result
timeit
说快了两倍一旦你持有循环中的最后一个值,你将不得不在循环后对其进行特殊处理。但是我的代码表明可以在循环内附加
sub_result
列表。