首先,你应该注意到你需要一个更好的数据结构。Python dicts 根本没有顺序,OrderedDict
只是保持插入顺序(因此您需要在每次键更改时重新排序)。一个排序的字典blist.sorteddict
,甚至一个排序的列表,blist.sortedlist
可能更适合您的需求。
我是否可以创建一个迭代器类(使用迭代器协议)来存储字典并使我能够以正向或反向顺序循环它们?我假设/猜测我可能需要首先分配一个属性值,该值将指示下一个循环是否应该是正向/反向。
您在这里不需要单独的迭代器类。您可以通过内置reversed
函数获得免费的前向迭代和后向迭代:
for key in mydict:
# do something
for key in reversed(mydict.keys()):
# do something
我可以在我的迭代器类中包含一个生成器函数(嵌套),这将使我能够检索下一个键吗?也就是说,超出或之前提供的整数?
当然,itertools
有很多功能可以让你做这样的事情:
from itertools import dropwhile, takewhile
# find next key beyond 4
next(dropwhile(lambda x: x <= 4, mydict))
# find last key before 20
next(dropwhile(lambda x: x >= 20, reversed(mydict.keys()))
您还可以将其打包成一个函数:
def first_beyond(pivot, seq):
next(dropwhile(lambda x: x <= pivot, seq))
first_beyond(4, mydict)
first_beyond(20, reversed(mydict.keys()))
同样,我是否有办法提供起点和终点并检索落在这些值之间的所有键(按排序顺序)?
您可以轻松地为此构建一个通用工具:
from itertools import dropwhile, takewhile
def between(begin, end, seq):
return takewhile(lambda x: x <= end,
dropwhile(lambda x: x < begin, seq))
像这样使用:
>>> list(between(4, 30, [1,2,4,8,16,32]))
[4, 8, 16]
编辑:如果您只需要偶尔检查排序的键,您可以将它们转换为排序列表并使用它们。成语和上面一样:
keys = sorted(mydict)
# forward and backward iteration
for k in keys:
# ...
for k in reversed(keys):
# ...
# function that returns a forward or backward iterator based on an argument
def forward_or_backward(seq, forward=True):
for x in (iter if forward else reversed)(seq):
yield x
# random access inside a loop
for i, key in enumerate(keys):
# next element
key[i+1]
# the between and first_beyond functions above also work for lists
您的其余功能可以从这些部分粘合在一起。请注意,创建一个特殊的类是不明智的,因为我们可以以一种足够通用的方式编写函数,以便它们适用于任何可迭代的对象,而不仅仅是您的键列表。