在 Python 3 中,dict_values、dict_keys 和 dict_items 不支持索引
my_dict = {'a': 0', 'b': 1', 'c': 2}
以下所有查询均失败:
my_dict.keys()[1]
my_dict.values()[1]
my_dict.items()[1]
出于这个原因。
有时我只想随机抽取字典中的内容。我知道我可以将它们的输出转换为列表。他们是否有任何其他不需要创建另一个数据结构的 getter 方法? (我还认为将它们转换为列表会创建一个副本,这可能不适用于大型词典)。
请您参考如下方法:
Sometimes I just want to get a random sample of what's in my dictionary. I know I can convert them their output to lists. Do they have any other getter methods that do not require creating another data structure? (I would also imagine that converting them to a list would create a copy, which may not work well for huge dictionaries).
key 类型在 Dictionary view objects 下进行了解释, 并且也保证是 collections.abc.KeysView 的子类和 friend 。基本上,这意味着您只能指望它们具有 __contains__、__iter__ 和 __len__。
它们不直接支持索引,因为它们的顺序可能会失效。*但实际上,在 Python 的任何实现中,只有当您改变字典时它们才会真正失效。这意味着你可以安全地做这样的事情:
next(itertools.islice(my_dict.keys(), i, None))
基本上,与索引 set 或任何其他可迭代的非迭代器的方式相同。
* 关于记录哪些行为的实际规则已经更改了几次。当前版本实际上说“他们提供了字典条目的动态 View ,这意味着当字典发生变化时, View 会反射(reflect)这些变化”,这意味着现在可以依赖实用规则。但是,即使您使用的是旧版本,例如,它明确地只保证对 keys、values、items 和相关函数,除非您担心有人编写 Python 2.6 或 3.1 或其他东西的新实现,否则没有理由为此担心。
当然,您可能希望将其包装在一个更具可读性的函数中。事实上,我会分两步来做。首先,使用 itertools recipes 中的 nth 函数:
def nth(iterable, n, default=None):
return next(itertools.islice(iterable, n, None), default)
然后结束键索引:
def getkey(mapping, index, default=None):
return nth(mapping.keys(), index, default)
如果你想要一个随机样本怎么办?好吧,字典 View 是 Sized 的,字典本身也是,所以您可以随时使用 randrange:
def choosekey(mapping):
return getkey(mapping, random.randrange(len(mapping)))
