在python中反转dict并访问其值的正确方法是什么?

时间:2018-04-25 08:55:25

标签: python dictionary mypy

以下代码完美地打印出cba mypy抱怨它。

main.py:10: error: No overload variant of "reversed" matches argument types [typing.ValuesView[builtins.str*]]

以相反顺序遍历x并获取值的正确方法是什么?

from collections import OrderedDict

def main() -> None:
    x = OrderedDict([
        (1, 'a'),
        (2, 'b'),
        (3, 'c'),
    ])

    for y in reversed(x.values()):
        print(y)


if __name__ == '__main__':
    main()

2 个答案:

答案 0 :(得分:2)

这是因为OrderedDict字典视图确实实现了__reversed__但不从collections.abc.Reversible继承(值视图继承自collections.abc.ValuesView)。

这可以通过在Python标准库中添加基类并更新Python Typeshed definition来解决。我filed an issue with the latter,因为这是解决问题的更快方法。

您可以克隆我的pull-request分支以在本地获取新定义,然后使用--custom-typeshed-dir切换到mypy将其用于编译到mypy本身的那个:

git clone https://github.com/mjpieters/typeshed.git \
    --branch ordereddict_views_reversible \
    ~/typeshed_ordereddict_views_reversible   # or a different location
mypy --custom-typeshed-dir ~/typeshed_ordereddict_views_reversible <yourproject>

答案 1 :(得分:1)

虽然它适用于Python 3.6,但在以前版本的Python 3中,您的代码并不起作用。在python 3.4:

TypeError: argument to reversed() must be a sequence

(与dict.values()的类型有关)

一种解决方法是先转换为list,但这样做很浪费。

for y in reversed(list(x.values())):
    print(y)

mypy尚未意识到这种新奇事物并发出错误。

你应该忽略那个错误。我没有尝试过,但可能会对# type: ignore作品进行评论(在https://github.com/python/mypy/issues/500中讨论过):

for y in reversed(list(x.values())):  # type: ignore