我在一个领域工作,在这个领域中,范围通常被包括在内地描述。我有人类可读的描述,例如from A to B,它表示包含两个端点的范围,例如from 2 to 4表示2, 3, 4。
在Python代码中使用这些范围的最佳方法是什么?以下代码可用于生成包含范围的整数,但我还需要执行包含切片操作:def inclusive_range(start, stop, step):
return range(start, (stop + 1) if step >= 0 else (stop - 1), step)
我看到的唯一完整解决方案是每次使用+ 1(或- 1)或切片表示法(例如range(A, B + 1)、l[A:B+1]、range(B, A - 1, -1))时显式使用+ 1(或- 1)。这种重复真的是处理包含范围的最佳方法吗?
编辑:感谢L3viathan的回答。写一个inclusive_slice函数来补充inclusive_range当然是一个选项,尽管我可能会这样写:def inclusive_slice(start, stop, step):
...
return slice(start, (stop + 1) if step >= 0 else (stop - 1), step)
这里的...表示处理负索引的代码,这在与切片一起使用时并不简单-注意,例如,如果slice_to == -1,l3viaan的函数会给出不正确的结果。
然而,似乎一个inclusive_slice函数会很难使用-l[inclusive_slice(A, B)]真的比l[A:B+1]更好吗?
有没有更好的方法来处理包含的范围?
编辑2:感谢您提供新答案。我同意Francis和Corley的观点,即改变slice操作的含义,无论是全局的还是某些类的,都会导致严重的混淆。因此,我现在倾向于编写一个inclusive_slice函数。
为了回答我之前编辑的问题,我得出的结论是,使用这样的函数(例如l[inclusive_slice(A, B)])比手动加/减1(例如l[A:B+1])要好,因为它允许在一个地方处理边案例(例如B == -1和B == None)。我们能减少使用这个函数时的尴尬吗?
编辑3:我一直在考虑如何改进用法语法,它目前看起来像l[inclusive_slice(1, 5, 2)]。特别是,如果创建的包含切片类似于标准切片语法,那将是很好的。为了允许这样做,而不是inclusive_slice(start, stop, step),可能有一个函数inclusive将切片作为参数。inclusive的理想用法语法是行1:l[inclusive(1:5:2)] # 1
l[inclusive(slice(1, 5, 2))] # 2
l[inclusive(s_[1:5:2])] # 3
l[inclusive[1:5:2]] # 4
l[1:inclusive(5):2] # 5
不幸的是,Python不允许这样做,它只允许在[]中使用:语法。inclusive因此必须使用语法2或3调用(其中s_的作用类似于the version provided by numpy)。
其他的可能性是使inclusive成为一个具有__getitem__的对象,允许语法4,或者只将inclusive应用于切片的stop参数,如语法5。不幸的是,我不相信后者能够工作,因为inclusive需要了解step值。
在可行的语法中(原始的l[inclusive_slice(1, 5, 2)],加上2,3和4),哪一个是最好的?或者还有其他更好的选择吗?
最后编辑:感谢大家的回复和评论,这非常有趣。我一直都是Python“单向”哲学的粉丝,但这个问题是由Python的“单向”和问题领域所禁止的“单向”之间的冲突引起的。我确实对语言设计中的TIMTOWTDI有些欣赏。
因为我给出了第一个也是最高票数的答案,所以我把奖金颁给了L3viathan。