我们以一个列表为例:
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]
并将它们完好无损地交出。
所以,我尝试修改生成器来解决这个问题:
Python 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)
).
Question
纠正此代码以处理尾随占位符的最佳方法是什么?
因为目标不是无论如何都要创建代码(我已经done it https://stackoverflow.com/questions/7745367/how-to-fill-the-start-and-the-end-of-a-unique-entry-with-the-same-value-in-numpy/7746150#7746150使用不同的技术),我想通过对代码进行一些修改来解决任务,而不是完全重写它。
这更像是一种训练,而不是真正的任务。
附加信息
window
代码来自here https://stackoverflow.com/questions/7636004/python-split-string-in-moving-window/7636587#7636587.
我的代码几乎与this https://stackoverflow.com/questions/7745367/how-to-fill-the-start-and-the-end-of-a-unique-entry-with-the-same-value-in-numpy/7747020#7747020@nye17 回答。但在这段代码中,作者对初始列表进行了就地修改。我想创建一个生成器,它将产生与该代码中的结果列表相同的值。
此外,我希望我的生成器接受任何可迭代对象作为参数,而不仅仅是列表(例如,它可以接受从文件中一一读取值的迭代器)。仅使用列表作为参数,任务变得更简单,因为我们可以从末尾扫描列表。
这不是我生活中必须解决的真正任务。这只是为了一次训练。
完整代码
http://codepad.org/9UJ9comY http://codepad.org/9UJ9comY