如何表示动态范围列表?

3 投票
3 回答
528 浏览
提问于 2025-04-18 13:59

在打印文档的页面时,比如说,你可以用一种简便的方式来指定你想打印的具体页码:

1, 3, 4-7, 9-

在一个有12页的文档中,这样的方式会打印出:

1, 3, 4, 5, 6, 7, 9, 10, 11, 12

我想知道如何在Python中表示这样的结构,这样我就可以查询某个特定的“页码”(这不仅限于打印;只是一个例子)是否在这个范围内,并且还能遍历这个范围。

如果这些页码是以简单的列表形式存在,就像第二个例子那样(把它转换成那样的字符串处理也很简单),那么这些事情就容易多了。但开放式的范围就带来了问题。在最后一刻之前,不能把它们简化成一个平坦的列表。

3 个回答

0

请原谅我这个新手的尝试,我用元组的列表来表示页面。

pages=[(1,1),(3,3),(4,7),(8,)]

def find_page(pages,page):
    for p in pages:
        if len(p)==1:
            if page >= p[0]:
                return True
            else:
                break
        if p[0]==p[1]:
            if page==p[0]:
                return True
        elif page >= p[0] and page <= p[1]:
            return True
1

如果我理解你的问题没错的话,你可以使用一个包含元组的列表。比如说,(1,1)表示第1页,(4, 7)表示第4、5、6和7页。比较棘手的部分是如何表示“从这一页到最后一页”。不过,如果你知道总页数的话,可以用float("inf")来解决这个问题。然后,扁平化的函数大概会是这样的:

def flatten_ranges(ranges, number_of_pages):
    flattened_list = []
    for item in ranges:
        page = item[0]
        while page <= item[1] and page <= number_of_pages:
            flattened_list.append(page)
            page += 1
    return flattened_list
0

我会使用一个生成器:

import itertools

def parse_ranges(ranges):
    for chunk in ranges.split(', '):
        if '-' not in chunk:
            chunk = chunk + '-' + chunk  # Turns 7 into 7-7 

        start, end = chunk.split('-')

        if end:
            yield from range(int(start), int(end) + 1)
        else:
            yield from itertools.count(int(start))

在你遍历它的时候,可以限制最大页码:

for page in parse_ranges('1, 3, 4-7, 9-'):
    if page > 20:
        break

    print(page)

或者单独处理这个问题:

def cap(iterable, maximum):
    for n in iterable:
        if n > maximum:
            break

        yield n

pages = list(cap(parse_ranges('1, 3, 4-7, 9-'), 20))

撰写回答