我们以一个列表为例:
a = [255, 255, 1, 255, 255, 255, 1, 2, 255, 255, 2, 255, 255, 3, 255, 3, 255, 255, 255]
255
是其中的一个特殊值。这是一个占位符。
我制作了一个生成器,它替换了列表中的一些占位符。它按预期工作。
但我不需要处理开始占位符[255, 255
和结束占位符255, 255, 255]
并原封不动地产生它们。
所以,我试图修改生成器来解决它:
蟒蛇 2.7
from __future__ import print_function
from itertools import tee, izip, ifilterfalse
def replace(iterable,placeholder=255):
it = enumerate(iterable) #the position is needed for the logic for the middle of the list
it = ifilterfalse(lambda x: x[1]==placeholder, it) #create an iterator that deletes all the placeholders
for i,(left,right) in enumerate(window(it,2)): #Slide through the filtered list with the window of 2 elements
if i==0: #Leaving the beginning placeholders intact
for j in range(left[0]):
yield placeholder
#SOME LOGIC FOR THE MIDDLE OF THE LIST (it works well)
#Need to leave the trailing placeholders intact.
转换为列表的中间值只是为了便于理解代码:
>>>iterable
[255,1,255,255,1,255,255,255,2,2,255,255,255,2,2,3,255,255,255,3,255,255]
>>>it = enumerate(iterable)
[(0, 255), (1, 1), (2, 255), (3, 255), (4, 1), (5, 255), (6, 255), (7, 255), (8, 2), (9, 2), (10, 255), (11, 255), (12, 255), (13, 2), (14, 2), (15, 3), (16, 255), (17, 255), (18, 255), (19, 3), (20, 255), (21, 255)]
>>>it = ifilterfalse(lambda x: x[1]==placeholder, it)
[(1, 1), (4, 1), (8, 2), (9, 2), (13, 2), (14, 2), (15, 3), (19, 3)]
>>>list(enumerate(window(it,2)))
[(0, ((1, 1), (4, 1))), (1, ((4, 1), (8, 2))), (2, ((8, 2), (9, 2))), (3, ((9, 2), (13, 2))), (4, ((13, 2), (14, 2))), (5, ((14, 2), (15, 3))), (6, ((15, 3), (19, 3)))]
因此,如您所见,list(enumerate(window(it,2)))
包含前导非占位符值的索引(0, ((**1**, 1), (4, 1))),
,但它不包含初始迭代器有多少尾随占位符的信息:list(enumerate(window(it,2)))
以该值结束,该值(6, ((15, 3), (**19**, 3)))
仅具有最后一个非占位符的索引占位符值,它不提供剩余多少占位符的信息。
我设法通过依赖it = enumerate(iterable)
哪个产生初始迭代器值的位置来处理领先的占位符,该初始迭代器值在第一个产生的值中持续存在ifilterfalse
。
但是我花了很多时间试图弄清楚如何对尾随占位符做同样的事情。问题是它ifilterfalse
只是吞下了最后一个占位符值,enumerate(iterable)
我看不到访问它们的方法(因为第一个生成的值ifilterfalse
包含 的值的索引,所以领先的占位符是可能的enumerate(iterable)
)。
问题
纠正此代码以处理尾随占位符的最佳方法是什么?
由于目标不是通过任何方式创建代码(我已经使用不同的技术完成了它),我想通过修改代码来解决这个任务,而不是完全重写它。
与其说是真正的任务,不如说是一种训练。
附加信息
window
是这里的代码。
我的代码与@nye17的这个答案几乎相同。但是在这段代码中,作者对初始列表进行了就地修改。我想创建一个生成器,它将产生与该代码中的结果列表相同的值。
此外,我希望我的生成器接受任何可迭代作为参数,而不仅仅是列表(例如,它可以接受从文件中一一读取值的迭代器)。由于只有列表作为参数,任务变得更简单,因为我们可以从末尾扫描列表。
这不是我在生活中必须解决的真正任务。这只是为了训练。