在多次尝试创建一个将反转键值对并反转OrderedDict的行程序之后,我得到了这样的结果:

    from collections import OrderedDict as OD

    attributes=OD((('brand','asus'), ('os','linux'), ('processor','i5'), ('memory','4G')))
    print(attributes)

    reversed_attributes=OD(reversed(list(attributes.items())))
    print(reversed_attributes)

    inverted_attributes=OD([reversed(item) for item in attributes.items()])
    print(inverted_attributes)

    ''' Prints
        OrderedDict([('brand', 'asus'), ('os', 'linux'), ('processor', 'i5'), ('memory', '4G')])
        OrderedDict([('memory', '4G'), ('processor', 'i5'), ('os', 'linux'), ('brand', 'asus')])
        OrderedDict([('asus', 'brand'), ('linux', 'os'), ('i5', 'processor'), ('4G', 'memory')])
    '''

这有效,但效率低吗?通过使用reversed(list(a.items()))这会产生大量开销,所以不是pythonic吗?对于反转的_属性也是如此。
关键是要避免for循环等等,但随着我们规模的扩大,这会降低性能吗?

最佳答案

有趣的是,我还想出了其他方法。

>>> from collections import OrderedDict as OD
>>> attributes = OD((('brand','asus'), ('os','linux'), ('processor','i5'), ('memory','4G')))

如果你想倒车,你可以这样做
>>> reverse = OD(attributes.items()[::-1])

或者更像蟒蛇的方法:
>>> reverse = OD(reversed(attributes.items()))

注意,您不需要创建listitems已经是一个列表,而reversed是一个生成器OrderedDict只需遍历它就可以生成新的dict。
都产生了相似的时间。
$ python -m timeit "from collections import OrderedDict as OD; attributes = OD((('brand','asus'), ('os','linux'), ('processor','i5'), ('memory','4G')))" "reverse = OD(attributes.items()[::-1])"
10000 loops, best of 3: 54.8 usec per loop
$ python -m timeit "from collections import OrderedDict as OD; attributes = OD((('brand','asus'), ('os','linux'), ('processor','i5'), ('memory','4G')))" "reverse = OD(reversed(attributes.items()))"
10000 loops, best of 3: 54.4 usec per loop
$ python -m timeit "from collections import OrderedDict as OD; attributes = OD((('brand','asus'), ('os','linux'), ('processor','i5'), ('memory','4G')))" "reversed_attributes=OD(reversed(list(attributes.items())))"
10000 loops, best of 3: 54.4 usec per loop

如果要反转:
>>> invert = OD(zip(*zip(*attributes.items())[::-1]))

或者更多的蟒蛇:
>>> invert = OD(map(reversed, attributes.items()))

同样,两者产生了相似的时间。
$ python -m timeit "from collections import OrderedDict as OD; attributes = OD((('brand','asus'), ('os','linux'), ('processor','i5'), ('memory','4G')));" "invert = OD(zip(*zip(*attributes.items())[::-1]))"
10000 loops, best of 3: 57 usec per loop
$ python -m timeit "from collections import OrderedDict as OD; attributes = OD((('brand','asus'), ('os','linux'), ('processor','i5'), ('memory','4G')));" "invert = OD(map(reversed, attributes.items()))"
10000 loops, best of 3: 56.8 usec per loop
$ python -m timeit "from collections import OrderedDict as OD; attributes = OD((('brand','asus'), ('os','linux'), ('processor','i5'), ('memory','4G')));" "inverted_attributes=OD([reversed(item) for item in attributes.items()])"
10000 loops, best of 3: 55.8 usec per loop

您可以将这两种方法同时用于反转和反转。
这有效,但效率低吗?通过使用reversed(list(a.items()))这会产生大量开销,所以不是pythonic吗?对于反转的_属性也是如此。
有些东西会产生很多开销,而且是蟒蛇式的;另一方面,有些东西非常有效,而不是蟒蛇式的,这个词有点被滥用了,但这只是我的观点
来自维基百科:
Python社区中一个常见的新词是pythonic,它可以具有与程序风格相关的广泛含义。说代码是pythonic就是说它很好地使用了Python的习惯用法,它是自然的,或者在语言中显示出流畅性。同样,如果说一个接口或语言特性是pythonic,那就是说它与Python习惯用法很好地结合在一起,它与其他语言很好地结合在一起。
相反,unpythic代码的一个标记是,它试图在Python中编写C++(或Lisp、Perl或Java)代码,即提供一个粗略的转录,而不是从另一种语言的形式的惯用翻译。pythonicity的概念与Python的可读性和避免“有不止一种方法”的极简哲学紧密相连。不可读的代码或不可理解的习语是不通俗的。
至于:
但随着规模的扩大,这会降低性能吗?
这很难说,如果不知道为什么要进行这样的转换,或者这些转换是否是系统的一个组成部分,从根本上说,它们只是增加了线性时间/空间开销,这可能是好的,也可能不是好的,如果条目数仍然很小,那么没有问题,但是如果每次请求时,假设这发生在一个web服务器上,您是在一个大的dicts上进行的,这可能会非常苛刻,可能需要重新设计以避免这种情况。

关于python - 有效地反向和反向python3.x OrderedDict,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11858960/

10-10 09:33