python - 有效地反转和反转 python3.x OrderedDict

标签 python dictionary python-3.x reverse performance

经过多次尝试创建将反转键值对并反转 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')])
    '''

这可行,但是效率低下吗?通过使用reverse(list(a.items()))会产生大量开销,所以不是pythonic吗?对于 inverted_attributes 也是如此。

重点是要避免 for 循环等,但是当我们扩大规模时,这会降低性能吗?

最佳答案

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

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

如果你想反转,可以这样做

>>> reverse = OD(attributes.items()[::-1])

或者更Pythonic的方法:

>>> reverse = OD(reversed(attributes.items()))

请注意,您不需要创建 list 项目已经是一个列表,而 reversed 是一个生成器 OrderedDict 将简单地迭代生成新的字典。

两者都产生相似的时序。

$ 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]))

或者更多Python风格:

>>> 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

您可以结合使用这两种方法来反转和反转。

This works, but is it inefficient? By using reversed(list(a.items())) is this creating a lot of overhead, and so is not pythonic? Same for the inverted_attributes.

某些东西可能会产生大量开销,并且是Pythonic,另一方面,有些东西可能非常非常高效,但不是很Pythonic,这个术语有点被滥用,但这只是我的观点

摘自维基百科:

A common neologism in the Python community is pythonic, which can have a wide range of meanings related to program style. To say that code is pythonic is to say that it uses Python idioms well, that it is natural or shows fluency in the language. Likewise, to say of an interface or language feature that it is pythonic is to say that it works well with Python idioms, that its use meshes well with the rest of the language.

In contrast, a mark of unpythonic code is that it attempts to write C++ (or Lisp, Perl, or Java) code in Python—that is, provides a rough transcription rather than an idiomatic translation of forms from another language. The concept of pythonicity is tightly bound to Python's minimalist philosophy of readability and avoiding the "there's more than one way to do it" approach. Unreadable code or incomprehensible idioms are unpythonic.

至于:

but will this decrease performance as we scale up?

这很难说,不知道为什么要进行这样的转换,或者它们是否是系统的组成部分,从根本上说,它们至少会增加线性时间/空间开销,这可能会或可能不好,如果条目数量仍然很小,那么没问题,但如果在每个请求中,假设这种情况发生在网络服务器上,您正在对大型字典执行此操作,这可能会非常苛刻,并且可能需要重新设计以避免这种情况。

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

相关文章:

python - 如何对多维字典中的值求和?

regex - 我编写了一个正则表达式来将子字符串与其周围的空格匹配,但这效果不佳

python - 手动设置图例中点的颜色

python - 比较两张图片以确定里面是否有相同的物体

python - 如何解析其中包含特定单词的行?

python - 字典中的重复项(Python)

dictionary - Idris 中字典/ map 的类型是什么

python - 菱形继承(钻石问题) - 多重继承 python - 只调用一次方法 - 但如何呢?

python - 使用 python 3.0 的 Numpy

python - Pandas 系列位到十进制整数