V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
alittlecode
V2EX  ›  Python

日常中如何解决 Python 中字典是无序这一问题的

  •  
  •   alittlecode · 2021-05-14 15:22:25 +08:00 · 3858 次点击
    这是一个创建于 1296 天前的主题,其中的信息可能已经有所发展或是发生改变。
    collections 的 OrderedDict 可以解决无序问题,但是他是按照你赋值的顺序实现的,比如我现在有一个 dict
    使用 OrderedDict 的话
    from collections import OrderedDict
    a = OrderedDict()
    a["aaa"] = 1
    a["bbb"] = 2
    这样情况下得出的是一个有序的字典 dict a = {"aaa": 1, "bbb": 2}
    如果我原本就有一个 dict b = {"ccc": 3, "ddd": 4}
    在不遍历重新赋值的情况下怎样让成为一个有序的字典
    35 条回复    2021-05-19 14:12:36 +08:00
    Jblue
        1
    Jblue  
       2021-05-14 15:26:41 +08:00
    secsilm
        2
    secsilm  
       2021-05-14 15:30:28 +08:00 via Android   ❤️ 5
    升级 Python 程序
    iyaozhen
        3
    iyaozhen  
       2021-05-14 15:34:23 +08:00
    不遍历好像不行

    话说你为啥需要有序?

    而且「有序」如何定义? key 有序?按什么排序,顺序、倒序?还是按 value ?
    jsutfun
        4
    jsutfun  
       2021-05-14 15:35:33 +08:00
    如果按 key 的话,python3 已经是有序的了呀
    allan888
        5
    allan888  
       2021-05-14 15:36:56 +08:00
    不用别的数据结构也行:
    from collections import OrderedDict

    d = {"ddd": 2, "ccc": 1}
    sorted_d = OrderedDict()
    l = d.keys()
    l.sort()
    for k in l:
    sorted_d[k] = d[k]
    alittlecode
        6
    alittlecode  
    OP
       2021-05-14 15:39:47 +08:00
    @iyaozhen 只是想让他按照我写的顺序显示比如 dict b 只是想在遍历是先出现 ccc 再出现 ddd
    alittlecode
        7
    alittlecode  
    OP
       2021-05-14 15:44:31 +08:00
    @allan888 不是为了排序只是为了按照我写的顺序展示根据 key 排序可以使用

    my_data = {'Python': 20, 'Swift':32, 'Kotlin': 43, 'Go': 25}
    # 创建基于 key 排序的 OrderedDict
    d1 = OrderedDict(sorted(my_data.items(), key=lambda t: t[0]))
    # 创建基于 value 排序的 OrderedDict
    d2 = OrderedDict(sorted(my_data.items(), key=lambda t: t[1]))
    alittlecode
        8
    alittlecode  
    OP
       2021-05-14 15:58:51 +08:00
    突然想到一个问题这个除非你提前设计好这个字段是怎样的,不然你就算写好一个字典,只是 ide 让你看到是这个顺序,保存到内存就完全变了,你看到的就是个假象,只是你看到的
    iyaozhen
        9
    iyaozhen  
       2021-05-14 16:00:47 +08:00 via Android
    你写的顺序这个计算机不好理解吧
    要不用 list ?
    alittlecode
        10
    alittlecode  
    OP
       2021-05-14 16:05:38 +08:00
    @iyaozhen 再维护一个 list 把所有的 key 写进去
    abersheeran
        11
    abersheeran  
       2021-05-14 16:49:50 +08:00
    升级 Python 版本就行了。
    aloxaf
        12
    aloxaf  
       2021-05-14 17:00:56 +08:00   ❤️ 1
    Python 3.6 中 dict 就已经有序了
    而 3.7 起 dict 保持插入顺序成为了正式的 feature
    所以,你该升级 Python 了……
    codists
        13
    codists  
       2021-05-14 17:15:46 +08:00
    没搞懂为什么那么多人说“升级 Python”或者“Python3.6 就已经有序了“,这个有序说的是插入的有序。而提问者的问题是”键按字母顺序排序或者按值排序“吧?
    aloxaf
        14
    aloxaf  
       2021-05-14 17:21:45 +08:00
    @codists #13 提问者在 6 楼和 7 楼都说了,「只是想让他按照我写的顺序显示」,「不是为了排序只是为了按照我写的顺序展示」
    llsquaer
        15
    llsquaer  
       2021-05-14 17:23:26 +08:00
    dict 现在已经有序了..但是有一次我发现 , 用 pyqt 发信号传 dict 数据..,还是出现了无序的问题..解决的方法是,转为元组,然后再 zip() 转为 dict
    chaleaoch
        16
    chaleaoch  
       2021-05-14 17:26:39 +08:00
    python3. 6 7 8 忘记是哪个版本 已经开始有序
    另外 OrderedDict 考虑一下.
    chaleaoch
        17
    chaleaoch  
       2021-05-14 17:27:29 +08:00
    楼主忽略 我没看正文.
    ch2
        18
    ch2  
       2021-05-14 17:28:40 +08:00
    字典本来就是不保证有序的
    weyou
        19
    weyou  
       2021-05-14 17:30:57 +08:00 via Android
    二楼已经给出方面答案了啊,要按照写的顺序就是升到 3.6
    xylophone21
        20
    xylophone21  
       2021-05-14 17:36:54 +08:00
    HashMap 是“无序”的,它的“序”靠的是 Hash 值,如果要“有序”可以用红黑树之类结构,但代价是你只能用你排序的那个字段做快速查找、插入了。

    如果即需要用 Key 快速查找、插入,又希望用别的参数来做“序”那么可能你需要一个符合的数据结构。
    Trim21
        21
    Trim21  
       2021-05-14 17:55:09 +08:00 via Android
    @ch2 dict 现在保证是有序的
    BBCCBB
        22
    BBCCBB  
       2021-05-14 18:00:36 +08:00
    @Trim21 保证有序也不对.. python3.5 还是 3.6+. 只是恰好实现的 dict 是有序的, 官方好像说不要依赖这个特性?? 因为他们不保证后续依然有序.
    Trim21
        23
    Trim21  
       2021-05-14 18:03:58 +08:00 via Android
    @BBCCBB
    3.6cpython 的实现是有序的

    然后 3.7 加入了语言特性
    renmu123
        24
    renmu123  
       2021-05-14 18:06:22 +08:00 via Android
    @BBCCBB 我记得后续的一个大版本已经确定这个 feature 了。
    你可以用[{}]进行遍历
    Trim21
        25
    Trim21  
       2021-05-14 18:12:02 +08:00 via Android
    我突然明白楼主的问题了,楼主说的是 dict 字面量的排序问题吧,这个好像没有保证过是有序的,保证的都是分别设置 key 的顺序。
    Trim21
        26
    Trim21  
       2021-05-14 18:13:00 +08:00 via Android
    应该只能 OrderedDict([(key,value),])这样了
    BBCCBB
        27
    BBCCBB  
       2021-05-14 18:15:04 +08:00
    @Trim21
    @renmu123
    学到了.. 要是有个链接更好了. 不是专业 python 搜这个有点恼火 🐶
    Trim21
        28
    Trim21  
       2021-05-14 18:18:16 +08:00 via Android
    @BBCCBB 是 guido 在邮件列表里说的…没有个 pep
    renmu123
        29
    renmu123  
       2021-05-14 19:03:06 +08:00
    https://docs.python.org/zh-cn/3/library/stdtypes.html#mapping-types-dict

    在 3.7 版更改: 字典顺序会确保为插入顺序。 此行为是自 3.6 版开始的 CPython 实现细节。
    seeleling
        30
    seeleling  
       2021-05-14 19:15:01 +08:00
    升级 Python
    francis59
        31
    francis59  
       2021-05-14 22:36:30 +08:00
    cherbim
        32
    cherbim  
       2021-05-15 12:14:02 +08:00 via iPhone
    不好意思,我的 Python 字典是有序的
    BBCCBB
        33
    BBCCBB  
       2021-05-15 13:44:52 +08:00
    @Trim21
    @renmu123
    那 OrderedDict 这个类在新版本里除了兼容老代码. 基本就没啥用了哈
    renmu123
        34
    renmu123  
       2021-05-15 15:44:53 +08:00
    @BBCCBB 还可以用来对字典顺序排序
    no1xsyzy
        35
    no1xsyzy  
       2021-05-19 14:12:36 +08:00
    @BBCCBB OrderedDict 可以手动调序,但操作极复杂,不推荐。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   930 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 20:57 · PVG 04:57 · LAX 12:57 · JFK 15:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.