我列表中有一系列项目。我想识别相同元素的运行并打印它们的起始位置和结束位置。例如,使用:
content=[c,c,c,c,f,f,f,f,c,c,b,b,b,b...]
我希望输出如下:
1-4 c
5-8 f
9-10 c
依此类推。这是我到目前为止所做的:
x=len(content)-1
i=0
y=0
z=0
for i in range(0,x):
if(content[i]==content[i+1]):
y=y+1
z=i-1
else:
print y
print content[z]
答案 0 :(得分:1)
第一个不是您的if
和else
,而是您如何循环。您似乎错过了对range
的调用,并且只有调用的参数。尝试:
for i in range(0, x):
现在将到达if
和else
块,您只需调整它们即可跟踪您关注的值。如果您想要开始和连续运行项目,您实际上并不需要这两个部分。试试这个:
run_start = 0
for i in range(len(content)-1):
if content[i] != content[i+1]: # only one branch needed, nothing to do when items are ==
print "{}-{} {}".format(run_start+1, i+1, content[i])
run_start = i+1
print "{}-{} {}".format(run_start+1, len(content), content[-1]) # extra code for the last run
如果运行中只有一个项目,则会打印3-3
之类的范围。如果您不想要,则可能需要添加另一个if
语句来检查i
和run_start
不相等(并打印其他内容,或跳过该运行如果他们是)。
我发现在可能的情况下,使用有意义的变量名称会非常有帮助。在这种情况下,我使用run_start
而不是y
或x
。
答案 1 :(得分:1)
Blckknght的解决方案很棒。我自己的版本更加冗长,以防止您理解整个过程背后的逻辑。您需要做的是遍历列表中的每个元素并将其存储在current
中,并将其与来自上一次迭代的last
(最后一个已知对象)进行比较。如果它们相同,则递增range_end
索引。如果它们不同,则表示新范围正在开始,因此您必须执行以下操作:
range_begin
,range_end
和current
元素。current
元素存储在last
中,因为它是新序列的第一个元素range_begin
和range_end
设置为当前i
要使整个过程正常工作,您需要在循环到last
列表的第一个元素之前初始化content
。
此外,由于索引i
从0开始,当我们同时打印range_begin
和range_end
时,我们只会将它们增加1。
content=['c','c','c','c','f','f','f','f','c','c','b','b','b','b']
range_begin=0
range_end=0
last=content[0] # store the first element as the last known
for i in range(0, len(content)):
current = content[i] # get the element from the list
if last != current: # compare to the last known, if different
print "{}-{} {}".format(range_begin+1, range_end+1, last) # print
last = current # store the current as last known
range_begin = i # reset the ranges to the current index
range_end = i
else:
range_end = i # if they are the same, just extend the range_end
同时检查: https://eval.in/575899
答案 2 :(得分:1)
您正在尝试解决一个非常重要的问题(如果还是相当简单),我建议您从标准库中获得帮助。 itertools
模块提供groupby
功能,几乎可以满足您的需求。给定一系列元素 x 1 ,..., x n 它将产生你对一个键 k 和一个非空的懒惰元素序列 g 进行配对( k , g )比较等于 k 。 (您可以将 g 转换为普通列表,方法是将list
应用到普通列表中。)
让我们试一试:
from itertools import groupby
items = "ccccffffccbbbb"
for (k, g) in groupby(items):
print k, list(g)
输出:
c ['c', 'c', 'c', 'c']
f ['f', 'f', 'f', 'f']
c ['c', 'c']
b ['b', 'b', 'b', 'b']
这看起来已经非常有用,但我们必须从相等项目列表中计算开始和结束索引。幸运的是,我们知道第一组的开始索引 - 它是1.如果我们知道任何组的开始索引,我们也知道它的结束索引,即开始索引加上组的长度减去1.开始索引下一组的将是当前组的开始索引加上当前组的长度。
这就是我们所需要的:
from itertools import groupby
items = "ccccffffccbbbb"
offset = 1
for (k, g) in groupby(items):
length = len(list(g)) # simple and does the job but not as efficient as it could be
print '{}-{} {}'.format(offset, offset + length - 1, k)
offset += length
输出:
1-4 c
5-8 f
9-10 c
11-14 b