Quantcast
Channel: CodeSection,代码区,Python开发技术文章_教程 - CodeSec
Viewing all articles
Browse latest Browse all 9596

Python 内建常量 Ellipsis

$
0
0

version python3.5.3

查阅 Python 文档时发现了这么一个常量 Ellipsis

文档中表述如下

EllipsisThe same as ... . Special value used mostly in conjunction with extended slicing syntax for user-defined container data types.

In [25]: ... is Ellipsis Out[25]: True

有了这个常量,我们便可以定义一些有趣的东西,比如一个和 Haskell 中类似的 list

λ [1, 2] [1,2] :: Num t => [t] λ [1..10] [1,2,3,4,5,6,7,8,9,10] :: (Enum t, Num t) => [t] λ [1, 4 .. 10] [1,4,7,10] :: (Enum t, Num t) => [t]

为此我们先来看看 Python 中的序列协议 __getitem__

In [1]: class Seq(object): ...: def __getitem__(self, key): ...: return key ...: In [2]: seq = Seq() In [3]: seq[1, 2, 3, 4, 5] Out[3]: (1, 2, 3, 4, 5) In [4]: seq[1:2] Out[4]: slice(1, 2, None) In [5]: seq[1:10:2] Out[5]: slice(1, 10, 2) In [6]: seq[3, 1:10:2] Out[6]: (3, slice(1, 10, 2))

我们可以看出,传入的是一个 tuple 类型,如果有切片操作的话,则对应一个 slice 对象

知道这点便好办了,至于无穷 list 我们可以使用 generator 来解决

class InfiniteSeq(object): def __getitem__(self, items): if isinstance(items, tuple): index = 0 while index < len(items): if items[index] is Ellipsis: end = items[index+1] if index+1 < len(items) else float('INF') if index > 1: step = items[index-1] - items[index-2] else: step = 1 if end > items[index-1] else -1 value = items[index-1] + step while (step > 0 and value <= end) or (step < 0 and value >= end): yield value value = value + step index = index + 1 else: yield items[index] index = index + 1 else: raise SyntaxError

测试结果

In [109]: seq = InfiniteSeq() In [110]: list(seq[1, 2, 3, 4, 5]) Out[110]: [1, 2, 3, 4, 5] In [111]: list(seq[1, ..., 5]) Out[111]: [1, 2, 3, 4, 5] In [112]: list(seq[1, 3, ..., 7]) Out[112]: [1, 3, 5, 7] In [113]: list(seq[1, 3, ..., 8]) Out[113]: [1, 3, 5, 7] In [114]: list(seq[1, 3, ..., 9]) Out[114]: [1, 3, 5, 7, 9] In [115]: list(seq[10, 1, 3, ..., 9, 12]) Out[115]: [10, 1, 3, 5, 7, 9, 12] In [116]: list(seq[10, ..., 1]) Out[116]: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] In [117]: list(seq[10, 8, ..., 0]) Out[117]: [10, 8, 6, 4, 2, 0] In [118]: for i in seq[1, ...]: ...: print(i) ...: if i > 5: ...: break ...: 1 2 3 4 5 6

Viewing all articles
Browse latest Browse all 9596

Trending Articles