我有这个问题。你知道吗
作为l
一个只包含0和1的列表,查找表示1的重复序列的开始和结束的所有元组。
示例
l=[1,1,0,0,0,1,1,1,0,1]
回答:
[(0,2),(5,8),(9,10)]
我用下面的代码解决了这个问题,但是我认为它非常混乱,我想知道是否有更干净的方法来解决这个问题(也许使用map/reduce?)你知道吗
from collections import deque
def find_range(l):
pairs=deque((i,i+1) for i,e in enumerate(l) if e==1)
ans=[]
p=[0,0]
while(len(pairs)>1):
act=pairs.popleft()
nex=pairs[0]
if p==[0,0]:
p=list(act)
if act[1]==nex[0]:
p[1]=nex[1]
else:
ans.append(tuple(p))
p=[0,0]
if(len(pairs)==1):
if p==[0,0]:
ans.append(pairs.pop())
else:
ans.append((p[0],pairs.pop()[1]))
return ans
代码:
输出:
用^{} 魔法:
输出:
或使用更有效的发电机功能:
作为一个简短的奖励,这里有另一种} )和提取非零项的索引(^{} ):
numpy
方法,虽然很复杂,但它是基于连续数字之间的离散差(^{代码:
逻辑:
indices
是索引列表,其中l元素=1=>;[0, 1, 5, 6, 7, 9]
diff
计算上面找到的索引之间的差异,并在开始处附加一个0以保持它们的长度相同=>;[0, 1, 4, 1, 1, 2]
change_ind
表示需要进行拆分的位置,对应于diff
大于1的位置。还要附加第一个索引和最后一个索引以供以后使用,否则您将只有中间元组=>;[0, 2, 5, 6]
split_indices
基于change_ind
中连续元素中指示的范围创建元组(使用zip创建范围的组合)=>;[(0, 1), (5, 6, 7), (9,)]
proper_tuples
循环通过在split_indices
中创建的元组,并确保如果元组的长度大于2,则只考虑第一个和最后一个元素,否则保持原样=>;[(0, 1), (5, 7), (9,)]
输出:
最终意见:
尽管这与OP在原问题中的建议不符:
它确实更有逻辑意义,似乎遵循OP在评论中指出的。你知道吗
例如,在
l
的开头有两个1—因此元组应该是(0, 1)
而不是(0, 2)
,以匹配建议的(start, end)
表示法。你知道吗同样地,在结尾只有一个元组-因此与之对应的元组是
(9,)
而不是(9, 10)
相关问题 更多 >
编程相关推荐