Python 如何表示范围的动态列表?
例如,从文档打印页面时,可以使用以下速记符号指定要打印的特定页码:Python 如何表示范围的动态列表?,python,range,Python,Range,例如,从文档打印页面时,可以使用以下速记符号指定要打印的特定页码: 1, 3, 4-7, 9- 在一份12页的文件中,这会打印出几页 1, 3, 4, 5, 6, 7, 9, 10, 11, 12 如何用Python表示这样的结构,以便查询特定的“页码”(不限于打印;这是一个示例)是否在范围内,以及是否在范围内循环 如果它们像第二个示例中那样位于扁平列表中,那么这些事情就很容易了(将其转换为扁平列表的字符串处理将非常简单),但是开放范围会带来问题。在最后一分钟之前不能将其展平。如果我正确理解
1, 3, 4-7, 9-
在一份12页的文件中,这会打印出几页
1, 3, 4, 5, 6, 7, 9, 10, 11, 12
如何用Python表示这样的结构,以便查询特定的“页码”(不限于打印;这是一个示例)是否在范围内,以及是否在范围内循环
如果它们像第二个示例中那样位于扁平列表中,那么这些事情就很容易了(将其转换为扁平列表的字符串处理将非常简单),但是开放范围会带来问题。在最后一分钟之前不能将其展平。如果我正确理解您的问题,您可以使用元组列表<代码>(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
def展平范围(范围、页数):
扁平化列表=[]
对于范围内的项目:
第页=项目[0]
当page时,我会使用生成器:
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))
请原谅我用元组列表作为页面的愚蠢尝试
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
pages=[(1,1),(3,3),(4,7),(8,)]
def查找页面(第页,第页):
对于第页中的p:
如果len(p)==1:
如果页面>=p[0]:
返回真值
其他:
打破
如果p[0]==p[1]:
如果页面==p[0]:
返回真值
如果第页>=p[0]和第页[1,3,4,5,6,9…页末]的列表不起作用吗?我相信你可以想出一些更好的方法,比如O(1)访问的dict,但我看不出你的问题。@EugeneK:是的,但是“页面结尾”可能会有所不同,范围需要在不同长度的集合上可用(因此列表不能预计算)。为什么不让一个numopages
和一个for循环将元素从标记添加到末尾?添加新“书”时,您只需更改页面。对不起,你能在这个问题上再澄清一点你想要什么吗。您是否在寻找一个比这更优雅的答案?最佳解决方案可能用于管理范围。请参阅模块。@rvighne实际上,您可以使用任何字符串x>y
为任何字符串x
和数字y
返回true。但是float(“inf”)
是一种更干净的解决方案;)所以基本上我只需要一个“现在开始直到结束”的标记。谢谢你给我看。你也可以用生成器和itertools来完成。islice
@Blender:你能详细说明一下吗?不要告诉我使用它的价值。@rvighne:我的错误,出于某种原因,我认为islice
强制了一个最大值。看起来不错,但成员资格测试很奇怪。如果我在parse_ranges(“”)
中执行x,如果x
确实在该范围内,它将返回True,但如果不是,解释器将挂起(Python 3.4.0)。我是否遗漏了一些关于生成器工作原理的基本知识?@rvighne:如果生成器的成员不是有限的,那么它们就不会很好地工作。将生成器转换为一个列表并使用它测试成员资格。我是否必须像您提供的那样在循环中手动执行此操作,或者有更好的方法吗?(正如所料,列表
构造函数不起作用。我可以为构造函数指定一个最大值吗?)。谢谢你的耐心。