字典的创建

字典中每个元素由一个键值对组成,其中键相当于真实字典中的字,它在整个字典中作为字条是唯一的;值相当于字的解释说明。Python中有字典数据类型,Excel VBA中则需要引外部库创建字典对象。

创建字典

【Excel VBA】

Excel VBA中没有字典数据类型,也无法直接创建字典对象,而需要通过引用第三方库创建字典对象并通过对该对象编程来实现字典相关的操作。

在Excel VBA中创建字典对象有前期绑定与后期绑定两种方式。

用后期绑定创建字典对象,首先创建一个Object类型的变量,然后用CreateObject函数创建字典对象并用该变量进行引用。使用类似下面的代码创建字典对象dicT。

code.vba
Dim dicT As Object
Set dicT = CreateObject("Scripting.Dictionary")

然后就可以使用字典对象的属性和方法进行编程,比如向字典对象添加键值对。示例文件的存放路径为Samples\ch08\Excel VBA\创建字典.xlsm。

code.vba
Sub Test()
  Dim dicT As Object
  Set dicT = CreateObject("Scripting.Dictionary")

  '向字典对象添加键值对
  dicT.Add "No001", "刘丹"
  dicT.Add "No002", "大谦"
  dicT.Add "No003", "马忠"
  Debug.Print dicT.Count  '3,字典的长度,即键值对的个数
End Sub

用前期绑定创建字典对象,需要按照下面的步骤进行操作:

在Excel主界面的“开发工具”功能面板中单击“Visual Basic”按钮,打开Excel的VBA开发环境。

在“工具”菜单中单击”引用”选项,打开“引用”对话框,如图8-1所示。

Document Image

图8-1 “引用”对话框

在“可使用的引用”列表框中选择“Microsoft Scripting Runtime”核选框。

单击“确定”按钮。

添加相关库的引用后,使用类似下面的代码创建字典对象dicT。

code.vba
Dim dicT As Scripting.Dictionary
Set dicT=New Scripting.Dictionary

或者

code.vba
Dim dicT As New Scripting.Dictionary

然后就可以使用字典对象的属性和方法进行编程,比如向字典对象添加键值对。示例文件的存放路径为Samples\ch08\Excel VBA\创建字典.xlsm。

code.vba
Sub Test2()
  Dim dicT As Scripting.Dictionary
  Set dicT = New Scripting.Dictionary

  '向字典对象添加键值对
  dicT.Add "No001", "刘丹"
  dicT.Add "No002", "大谦"
  dicT.Add "No003", "马忠"
  Debug.Print dicT.Count  '3
End Sub

【Python】

Python中有字典数据类型。字典的键与值之间用冒号分隔,键值对之间用逗号分隔。整个字典用大括号({})包围。注意,在整个字典中,键必须是唯一的。

下面用{}创建字典:

code.python
>>> dt={}    #空字典
>>> dt
{}
>>> dt={'No001':'刘丹', 'No002':'大谦', 'No003':'马忠'}
>>> dt
{'No001': '刘丹', 'No002': '大谦', 'No003': '马忠'}
>>> len(dt)  #字典的长度
3

Excel VBA中后期绑定与前期绑定的比较

8.1.1小节中Excel VBA部分用后期绑定和前期绑定实现了字典对象的创建,这两种实现方式有什么区别呢?主要区别在于两种实现方式对程序运行效率的影响,使用前期绑定比用后期绑定的运行效率往往要快得多。

为了比较两种绑定方式的工作效率,在Excel VBA编程环境中新建一个模块,添加下面的代码。代码有LB和FB两个过程,分别用于计算后期绑定和前期绑定两种方式完成一万次添加键值对时花费的时间。使用API函数timeGetTime进行计时,该函数能精确到毫秒,在模块顶部对该函数进行声明。示例文件的存放路径为Samples\ch08\Excel VBA\创建字典.xlsm。

code.vba
Private Declare Function timeGetTime Lib "winmm.dll"() As Long
Sub LB()
  '后期绑定时计算一万次添加键值对的用时
  Dim dblStart As Double
  Dim dblEnd As Double
  Dim lngI As Long
  '后期绑定
  Dim dicT As Object
  Set dicT = CreateObject("Scripting.Dictionary")
  dblStart = timeGetTime  '起始时间
  For lngI = 1 To 10000
    dicT.Add lngI, "刘丹"
  Next
  dblEnd = timeGetTime  '终止时间
  Debug.Print "后期绑定用时:" & CStr(dblEnd - dblStart)  '用时
  Set dicT = Nothing
End Sub
Sub FB()
  '前期绑定时计算一万次添加键值对的用时
  Dim dblStart As Double
  Dim dblEnd As Double
  Dim lngI As Long
  '前期绑定
  Dim dicT As Scripting.Dictionary
  Set dicT = New Scripting.Dictionary
  dblStart = timeGetTime  '起始时间
  For lngI = 1 To 10000
    dicT.Add lngI, "刘丹"
  Next
  dblEnd = timeGetTime  '终止时间
  Debug.Print "前期绑定用时:" & CStr(dblEnd - dblStart)  '用时
  Set dicT = Nothing
End Sub

先后执行LB和FB过程,在立即窗口中输出后期绑定和前期绑定两种方式下一万次添加键值对的用时:

code.vba
后期绑定用时:31
前期绑定用时:11

可见使用前期绑定时工作效率有明显优势。

除了工作效率有明显优势外,使用前期绑定还可以获得另外一些好处。首先,在图8- 所示的“引用”对话框中引用“Microsoft Scripting Runtime”选项对应的库以后,可以用编程环境提供的对象浏览器查看该库提供的对象。

在编程环境的“视图”菜单中单击“对象浏览器”选项,打开对象浏览器如图8-2中红框内所示。

Document Image

图8-2 对象浏览器

在对象浏览器左上角的下拉式列表框中选择库的名称Scripting,该库左侧列表框中显示该库中的所有类和公共枚举类型。选择一个类以后,右侧列表框中选择该类的成员,包括属性、方法和事件等。图8- 中显示了字典对应的Dictionary类的成员。选择类或类的成员名称后,底部灰色区域显示对应项的简单说明。

另外,在代码编辑器中用点引用前期绑定方式创建的字典对象的属性或方法时,会自动弹出该对象对应的属性和方法名称组成的智能提示列表框,如图8-3所示。这样,只需要用鼠标在列表框中点选即可输入属性或方法名称,不需要记忆,从而提高编程效率。使用后期绑定创建的字典对象则没有这个功能,即用点引用对象的属性和方法时没有这个智能提示列表框。

Document Image

图8-3 智能提示列表框

Python中更多创建字典的方法

使用dict函数可以创建字典。该函数的参数,可以以key=value的形式连续传入键和值,也可以将其他可迭代对象转换为字典,或者zip函数生成zip对象,然后将zip对象转换为字典。

下面用key=value的形式输入键和值,并生成字典。

code.python
>>> dt=dict(grade=5, clas=2, id="s195201", name="LinXi")
>>> dt
{'grade': 5, 'clas': 2, 'id': 's195201', 'name': 'LinXi'}

下面用dict函数将其他可迭代对象转换为字典,其他可迭代对象包括列表、元组、集合等。

code.python
>>> dt=dict([("grade",5), ("clas",2), ("id","s195201"), ("name", "LinXi")])
>>> dt=dict((("grade",5), ("clas",2), ("id","s195201"), ("name", "LinXi")))
>>> dt=dict([["grade",5], ["clas",2], ["id","s195201"], ["name", "LinXi"]])
>>> dt=dict((["grade",5], ["clas",2], ["id","s195201"], ["name", "LinXi"]))
>>> dt=dict({("grade",5), ("clas",2), ("id","s195201"), ("name", "LinXi")})

这几种转换得到的结果均为:

code.python
>>> dt
{'grade': 5, 'clas': 2, 'id': 's195201', 'name': 'LinXi'}

使用zip函数可以利用两个给定的列表得到zip对象,然后用dict函数将该zip对象转换为字典。这适合于分别得到键和值序列,然后组装成字典的情况。

code.python
>>> k=["grade", "clas", "id", "name"]
>>> v=[5, 2, "s195201", "LinXi"]
>>> p=zip(k,v)
>>> dt=dict(p)
>>> dt
{'grade': 5, 'clas': 2, ' id': 's195201', 'name': 'LinXi'}

使用fromkeys方法可以创建值为空的字典,例如:

code.python
>>> dt=dict.fromkeys(["grade", "clas", "id", "name"])
>>> dt
{'grade': None, 'clas': None, ' id': None, 'name': None}