Python的字典(Dictionary)按顺序遍历

!本文可能 超过1年没有更新,今后内容也许不会被维护或者支持,部分内容可能具有时效性,涉及技术细节或者软件使用方面,本人不保证相应的兼容和可操作性。

最近尝试着改用Python取代VBScript来实现一些功能,当然也遇到了一些麻烦,这里我要说明的是Python的字典和VBScript所调用的字典对象是有些区别的。

字典可以叫做哈希(Hash)表或者K-V存储表(Key-Value),也就是说一个独立的键值对应一条数据,Key是不能重复的,因为需要快速索引数据,字典进行数据查找,效率是很高的,当然其效率是靠空间换来的。

好了,说了这么多,下面介绍下,我遇到的一点区别,在VBScript中不原生支持字典特性,不过我们可以通过CreateObject(“Scripting.Dictionary”)来创建一个字典对象,然后通过Add方法添加Key Value,也可以说我比较的是Python和Scripting.Dictionary组件对象的区别,我在前面的文章中简单的介绍过这个对象相关的使用方法,这里再给出相应的脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Dim objDict
Set objDict = CreateObject("Scripting.Dictionary")
 
  objDict.Add "b", "2"
  objDict.Add "a", "1"
  objDict.Add "c", "3"
  objDict.Add "e", "5"
  objDict.Add "d", "4"
 
  ' 以下是遍历字典
  Dim objKeys, objItems, i
  objKeys = objDict.Keys
  objItems = objDict.Items
  For i = 0 To objDict.Count -1
    WSH.Echo objKeys(i) &_
             " " & objItems(i)
  Next
 
  objDict.RemoveAll
Set objDict = Nothing
 
' -- OUTPUT --
' b 2
' a 1
' c 3
' e 5
' d 4

通过上面的代码可以看出Scripting.Dictionary遍历字典的输出顺序是按照我们调用add添加字典元素的顺序,由于Python语言原生支持字典属性,因此调用上面会方便很多:

dict = {"b":"2", "a":"1",
        "c":"3", "e":"5", "d":"4"}
 
for key,value in dict.items():
    print(key,value)
 
# -- OUTPUT --
# a 1
# c 3
# b 2
# e 5
# d 4

但是输出的顺序却不是我们预想的那样初始化的顺序,查询相关文献得知,Python保证遍历字典所有元素,但不保证遍历的顺序,假如我们期望按预先的顺序进行遍历的话,我目前找到一个办法,就是通过两个List分别存储Key和Value,然后通过zip合并为Dictionary,再遍历:

# 通过zip方法合并两个List为Dictionary
# 遍历会按原先的顺序
keys = ["b", "a", "c", "e", "d"]
values = ["2", "1", "3", "5", "4"]
 
for key,value in zip(keys, values):
    print(key,value)
 
# -- OUTPUT --
# b 2
# a 1
# c 3
# e 5
# d 4

然后我突发奇想,将Dictionary的keys()和values()集合调用zip,然后遍历会不会是按顺序的呢?很遗憾,答案是否定的,最后Python遍历字典的测试代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# -*- coding:UTF-8 -*-
 
import os
 
def main():
    dict = {"b":"2", "a":"1",
            "c":"3", "e":"5", "d":"4"}
 
    for key,value in dict.items():
        print(key,value)
 
    print("-------------------")
 
    for i,value in enumerate(dict):
        print(i,value)    
 
    print("-------------------")
 
    # 通过zip方法合并两个List为Dictionary
    # 遍历会按原先的顺序
    keys = ["b", "a", "c", "e", "d"]
    values = ["2", "1", "3", "5", "4"]
 
    for key,value in zip(keys, values):
        print(key,value)
 
    print("-------------------")
 
    # 直接通过zip,字典keys和values集合
    # 遍历依旧不会按照初始顺序
    for key,value in zip(dict.keys(), dict.values()):
        print(key,value)
 
    pause()
 
def pause():
    os.system("PAUSE")
 
if __name__ == '__main__':
    main()
 
# -- OUTPUT --
# a 1
# c 3
# b 2
# e 5
# d 4
# -------------------
# 0 a
# 1 c
# 2 b
# 3 e
# 4 d
# -------------------
# b 2
# a 1
# c 3
# e 5
# d 4
# -------------------
# a 1
# c 3
# b 2
# e 5
# d 4

如果找到什么好的办法我再更新吧:-)

2013年8月27日更新

Python的collections包中有个非常有用的类型OrderedDict可以实现顺序字典功能。

若无特别说明,本网站文章均为原创,原则上这些文章不允许转载,但是如果阁下是出于研究学习目的可以转载到阁下的个人博客或者主页,转载遵循创作共同性“署名-非商业性使用-相同方式共享”原则,请转载时注明作者出处谢绝商业性、非署名、采集站、垃圾站或者纯粹为了流量的转载。谢谢合作!

  1.  按博主的写法,分别用两个容器分别存储key跟value,然后用zip合并为dict类型,最后输出是要求顺序排列,那么,只要把zip返回值用sorted()排序即可。

    • 我的意思不一定是按数值自然顺序排列,主要是自定义顺序,比如我指定 [4,7,2,9,1,3] 为顺序序列,那么sorted就不符合要求了。

请稍后...

发表评论

电子邮件地址不会被公开。 必填项已用*标注