Python 外层循环从内层循环继续
我正在遍历一系列数字,想找出一些数字的范围(比如小于100的数字)。
举个例子: 列表 = [1, 2, 3, 125, 7, 8, 9, 200]。 我想把结果写到一个文件里:1-3, 7-9。 我遇到的问题是,外层循环会在内层循环中重复遍历某些项目,所以我得到的输出是:1-3, 2-3, 3, 7-9, 8-9, 9。
我现在的策略是这样的,能正常工作:
counter = 1
for i in range(len(list)): # outer loop
if counter > 1: # prevents the outer loop from iterating the numbers iterated in inner loop
counter -= 1
continue
elif counter <=1:
while list[i] < 100:
i +=1
counter +=1
if list[i] > 100:
print list[i-counter], '-', list[i]
break
我在想有没有更“pythonic”的方法,让外层循环跳过那些已经在内层循环中遍历过的项目,而不是像我上面那样使用额外的计数器。谢谢。
补充说明:有一些回复关注了连续数字。我的错误是,数字不一定要连续。我只需要那个范围内的第一个和最后一个数字。 举个例子,列表 = [1, 4, 8, 12, 57, 200, 4, 34, 300]。输出:1 - 57, 4 - 34。 这个列表和条件是用户决定的。条件总是一个数字和比较运算符‘<’。谢谢。
3 个回答
0
使用 zip()
函数:
zip(lis, lis[1:])
会返回类似下面的内容:
[(0, 1),
(1, 2),
(2, 3),
(3, 5),
(5, 6),...]
现在你可以遍历这个列表,检查它们之间的差值是否为1。
代码:
In [103]: def ranges(lis):
ans=[]
z=zip(lis,lis[1:])
for x,y in z:
if y-x==1:
ans.extend([x,y])
else:
if ans:
yield "{0}-{1}".format(min(ans),max(ans))
ans=[]
if ans:
yield "{0}-{1}".format(min(ans),max(ans))
.....:
In [104]: lis=[0,1,2,3,5,6,7,8,10,11,2,3,4]
In [105]: list(ranges(lis))
Out[105]: ['0-3', '5-8', '10-11', '2-4']
2
这里介绍一种不同的方法,使用的是“while”循环:
def print_ranges(given_list, limit):
while given_list:
start = end = given_list.pop(0)
if start < limit:
while given_list and (given_list[0] < limit):
end = given_list.pop(0)
if (end != start):
print "%d-%d"%(start,end) # or save it in another list
接下来是一些测试:
>>> print_ranges([1,4,8, 200, 4,34, 72, 300], 100)
1-8
34-72
>>> print_ranges([1, 4, 8, 12, 57, 200, 4, 34, 300], 100)
1-57
4-34
>>> print_ranges([1, 4, 8, 12, 57, 200, 4, 34, 300], 250)
1-34
4
你不需要用两个循环,一个就够了:
def ranges(seq):
it = iter(seq)
start = end = next(it)
for val in it:
if val == end + 1:
end = val
else:
if end - start > 1:
yield start, end
start = end = next(it)
for start, end in ranges([1, 2, 3, 125, 7, 8, 9, 200]):
print('%d-%d' % (start, end))
这个逻辑和你想的稍微有点不同:它是寻找由连续数字组成的子序列(比如你例子中的 1 2 3
和 7 8 9
)。如果需要的话,改变这个逻辑也很简单,可以让它在任何大于等于 100
的数字处断开序列。