[英]Determine sequential numbers in a list (Python)
我試圖找到最pythonic的方法來找出列表中的數字是否是連續的。 為了提供一些背景信息,我收集了一個文件夾中存在的數字列表,我需要找出缺少哪些數字。
我收集了所有的數字,然后從范圍(開始,結束+1)中列出應該有哪些數字。 我很容易地做了一些東西來向我展示所有丟失的數字:
missing = [x for x in existingNumbers if x not in shouldBeNumbers]
問題是,如果我打印出所有這些,有很多數字可以壓縮(即 1、2、3、4、7、10 可以打印為 1-4、7、10),因為可以大量數字丟失。
我嘗試了兩種方法:
對於這兩種方式,frameRange 是 range(startFrame, endFrame+1) 並且 frameList 是從當前存在的內容生成的列表。
1)
for x in frameRange:
if x not in frameList:
if originalFrame == None:
originalFrame = x
elif originalFrame:
if lastFrame == None:
lastFrame = x
elif lastFrame:
if lastFrame == x-1:
lastFrame = x
else:
if originalFrame != lastFrame:
missingFrames.append(str(originalFrame)+"-"+str(lastFrame))
originalFrame = x
lastFrame = x
else:
missingFrames.append(str(originalFrame))
originalFrame = x
lastFrame = x
if x == endFrame:
if originalFrame != lastFrame:
missingFrames.append(str(originalFrame)+"-"+str(lastFrame))
originalFrame = x
lastFrame = x
else:
missingFrames.append(str(originalFrame))
originalFrame = x
lastFrame = x
2)
i = 0
while i < len(frameRange):
if frameRange[i] in frameList:
i += 1
else:
if i + 1 < len(frameRange):
if frameRange[i + 1] in frameList:
missingFrames.append(str(frameRange[i]))
i += 1
else:
j = 1
while frameRange[i+j] not in frameList:
aheadFrameNumber = int(str(j))
if i + j + 1 < len(frameRange):
j += 1
else:
break
missingFrames.append(str(frameRange[i])+"-"+str(frameRange[aheadFrameNumber]))
if i + aheadFrameNumber + 1 < len(frameRange):
i += aheadFrameNumber + 1
else:
missingFrames.append(str(frameRange[i]))
第一種方法是有效的,但由於它發生在當前幀檢查最后一幀時,每當最后一幀消失時,它不會 append 是列表中最后一個缺失的部分。 對於第二種方式,我必須將所有內容都包含在 if 語句中,因為在前進時我不斷收到索引異常。
我想我必須退后一步,重新思考,並以不同的方式處理它。 我想知道在 python 中是否有更好的方法來做到這一點,我還沒有想到,因為我不知道 function。 兩種方式都開始有點失控了。
嘗試這樣的事情
missing=[]
numbers.insert(0, 0) # add the minimum value on begining of the list
numbers.append(41) # add the maximum value at the end of the list
for rank in xrange(0, len(numbers)-1):
if numbers[rank+1] - numbers[rank] > 2:
missing.append("%s-%s"%(numbers[rank] +1 , numbers[rank+1] - 1))
elif numbers[rank+1] - numbers[rank] == 2:
missing.append(str(numbers[rank]+1))
print missing
對於numbers = [1,4,6,10, 12,]
並且應該存在的數字是從 1 到 40,您將擁有:
['2-3', '5', '7-9', '11', '13-40']
def find_missing_range(my_numbers, range_min, range_max):
expected_range = set(range(range_min, range_max + 1))
return expected_range - set(my_numbers)
def numbers_as_ranges(numbers):
ranges = []
for number in numbers:
if ranges and number == (ranges[-1][-1] + 1):
ranges[-1] = (ranges[-1][0], number)
else:
ranges.append((number, number))
return ranges
def format_ranges(ranges):
range_iter = (("%d" % r[0] if r[0] == r[1] else "%d-%d" % r) for r in ranges)
return "(" + ", ".join(range_iter) + ")"
def main(my_numbers, range_min, range_max):
numbers_missing = find_missing_range(my_numbers, range_min, range_max)
ranges = numbers_as_ranges(numbers_missing)
return format_ranges(ranges)
if __name__ == '__main__':
range_min, range_max = 1, 40
print main([1, 4, 6, 10, 12], range_min, range_max)
print main([1, 2, 3, 4, 10, 20], range_min, range_max)
(2-3, 5, 7-9, 11, 13-40)
(5-9, 11-19, 21-40)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.