简体   繁体   English

确定列表中的序号(Python)

[英]Determine sequential numbers in a list (Python)

I'm trying to find the most pythonic way to find out if numbers in a list are sequential.我试图找到最pythonic的方法来找出列表中的数字是否是连续的。 To give some background, I have a list of numbers gathered that exist in a folder, and I need to find out which numbers are missing.为了提供一些背景信息,我收集了一个文件夹中存在的数字列表,我需要找出缺少哪些数字。

I gather all of the numbers, and then make another list from the range(beginning, end+1) of what numbers should be there.我收集了所有的数字,然后从范围(开始,结束+1)中列出应该有哪些数字。 I very easily made something to show me all of the numbers missing:我很容易地做了一些东西来向我展示所有丢失的数字:

missing = [x for x in existingNumbers if x not in shouldBeNumbers]

The problem is that if I print out all of those, there are a lot of numbers that could be condensed (ie 1, 2, 3, 4, 7, 10 could be printed as 1-4, 7, 10) because there could be massive amounts of numbers missing.问题是,如果我打印出所有这些,有很多数字可以压缩(即 1、2、3、4、7、10 可以打印为 1-4、7、10),因为可以大量数字丢失。

I've tried two approaches:我尝试了两种方法:

For both ways, frameRange is range(startFrame, endFrame+1) and frameList is a list generated from what exists currently.对于这两种方式,frameRange 是 range(startFrame, endFrame+1) 并且 frameList 是从当前存在的内容生成的列表。

1) 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) 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]))

The first way was working, but since it happens on the current frame checking the last, whenever the last frame was gone it wouldn't append the last missing section to the list.第一种方法是有效的,但由于它发生在当前帧检查最后一帧时,每当最后一帧消失时,它不会 append 是列表中最后一个缺失的部分。 For the second way I had to keep wrapping everything in if statements because I kept getting index exceptions when moving forwards.对于第二种方式,我必须将所有内容都包含在 if 语句中,因为在前进时我不断收到索引异常。

I think I have to step back, re-think, and approach it differently.我想我必须退后一步,重新思考,并以不同的方式处理它。 I'm wondering if there is a much better way to do this in python that I haven't thought about yet because I don't know the function.我想知道在 python 中是否有更好的方法来做到这一点,我还没有想到,因为我不知道 function。 Both ways started to get a little out of hand.两种方式都开始有点失控了。

Try something like this尝试这样的事情

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

which for numbers = [1,4,6,10, 12,] and numbers should be present are from 1 to 40 you will have:对于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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM