Dictionary Application Examples

To help readers consolidate what they have learned in this chapter, this section provides 3 examples related to dictionaries, with both Excel VBA and Python versions of the code.

Application Example 1: Count Occurrences of Unique Values in Multiple Rows of Data

As shown in Figure 8-5, columns B–H list multiple rows of personnel names, with many repeated names. The task is to calculate the occurrence count of each name.

Document Image

Figure 8-5

Solution idea: Create a dictionary and iterate through all names. If the current name is not yet a key in the dictionary, add it with a value of 1; if it already exists, increment its value by 1.

[Excel VBA] Sample file path: Samples\ch08\Excel VBA\Count Unique Value Occurrences in Multiple Rows.xlsm.

code.vba
Sub Test()
    Dim arr               ' Store original data
    Dim intI As Integer
    Dim intJ As Integer
    Dim d As Dictionary   ' Dictionary object
    Set d = New Dictionary
    On Error Resume Next
    ' Get original data
    arr = ActiveSheet.Range("B2:H10").Value
    For intI = 1 To UBound(arr, 1)
        For intJ = 1 To UBound(arr, 2)
            ' Iterate each cell, skip empty
            If arr(intI, intJ) <> "" Then
                ' If name exists in dictionary, increment count
                If d.Exists(arr(intI, intJ)) Then
                    d(arr(intI, intJ)) = d(arr(intI, intJ)) + 1
                Else
                    ' Not exist, add key-value pair, value = 1
                    d.Add arr(intI, intJ), 1
                End If
            End If
        Next
    Next
    ' Output all keys (unique names) and counts
    ActiveSheet.Range("J2").Resize(d.Count, 1).Value = _
        Application.WorksheetFunction.Transpose(d.Keys)
    ActiveSheet.Range("K2").Resize(d.Count, 1).Value = _
        Application.WorksheetFunction.Transpose(d.Items)
End Sub

Running the program outputs results in columns J and K of Figure 8-5.

[Python] Sample data file path: Samples\ch08\Python\Count Unique Value Occurrences in Multiple Rows.xlsx, .py file in same directory named sam08-01.py.

code.python
class="text-secondary">import xlwings class="text-secondary">as xw       # Import xlwings package
class="text-secondary">from xlwings.constants class="text-secondary">import Direction
class="text-secondary">import os                   # Import os package
# Get current path of .py file
root = os.getcwd()
# Create Excel application, visible, no workbook initially
app = xw.App(visible=True, add_book=False)
# Open data file, writable
bk = app.books.open(fullname=root + r'\Count Unique Value Occurrences in Multiple Rows.xlsx', read_only=False)
sht = bk.sheets(1)         # Get first worksheet
d = {}
arr = sht.range('B2:H10').value   # Get data
for i in range(len(arr)):          # Row
    for j in range(len(arr[0](@ref)):   # Column
        # Iterate each cell, skip empty
        if arr[i][j] is not None:
            if arr[i][j] in d:              # If already in dictionary
                d[arr[i][j]] = d[arr[i][j]] + 1   # Increment count
            else:
                d[arr[i][j]] = 1             # Add new key-value, value = 1
# Output unique names and counts
sht.range('J2').options(transpose=True).value = list(d.keys())
sht.range('K2').options(transpose=True).value = list(d.values())

Running the program outputs results in columns J and K of Figure 8-5.

Application Example 2: Summarize Player Awards

As shown in Figure 8-6, columns A–C list winners of the Ballon d'Or, Best Player, and Golden Boot. The task is to summarize awards for each player.

Document Image

Figure 8-6

Solution idea: Create a dictionary, iterate through all player names. If a name is not yet a key, add it with the current award as value; if it exists, append the current award to the existing value.

[Excel VBA] Sample file path: Samples\ch08\Excel VBA\Summarize Player Awards.xlsm.

code.vba
Sub Test()
    Dim intI As Long
    Dim intR As Long
    Dim d As Dictionary   ' Dictionary object
    Set d = New Dictionary
    Dim sht As Object
    Set sht = ActiveSheet
    On Error Resume Next
    intR = sht.Range("A1").End(xlDown).Row   ' Row count of column A
    For intI = 2 To intR
        ' Add A column data to dictionary, player name as key, value = "Ballon d'Or"
        d.Add sht.Cells(intI, 1).Value, "Ballon d'Or"
    Next
    intR = sht.Range("B1").End(xlDown).Row   ' Row count of column B
    For intI = 2 To intR
        ' Check if player name exists in dictionary
        If d.Exists(sht.Cells(intI, 2).Value) Then
            ' If exists, append ",Best Player"
            d(sht.Cells(intI, 2).Value) = _
                d(sht.Cells(intI, 2).Value) & ",Best Player"
        Else
            ' Not exist, add new key-value
            d.Add sht.Cells(intI, 2).Value, "Best Player"
        End If
    Next
    intR = sht.Range("C1").End(xlDown).Row   ' Row count of column C
    For intI = 2 To intR
        ' Check if player name exists
        If d.Exists(sht.Cells(intI, 3).Value) Then
            ' Append ",Golden Boot"
            d(sht.Cells(intI, 3).Value) = _
                d(sht.Cells(intI, 3).Value) & ",Golden Boot"
        Else
            d.Add sht.Cells(intI, 3).Value, "Golden Boot"
        End If
    Next
    ' Output dictionary data, column E = player name, F = awards
    sht.Range("E1").Resize(d.Count, 1).Value = _
        Application.WorksheetFunction.Transpose(d.Keys)
    sht.Range("F1").Resize(d.Count, 1).Value = _
        Application.WorksheetFunction.Transpose(d.Items)
End Sub

Running the program outputs results in columns E and F of Figure 8-6.

[Python] Sample data file path: Samples\ch08\Python\Summarize Player Awards.xlsx, .py file named sam08-02.py.

code.python
class="text-secondary">import xlwings class="text-secondary">as xw
class="text-secondary">from xlwings.constants class="text-secondary">import Direction
class="text-secondary">import os
root = os.getcwd()
app = xw.App(visible=True, add_book=False)
bk = app.books.open(fullname=root + r'\Summarize Player Awards.xlsx', read_only=False)
sht = bk.sheets(1)
# Get last row number of each column
row_num_1 = sht.api.Range('A1').End(Direction.xlDown).Row
row_num_2 = sht.api.Range('B1').End(Direction.xlDown).Row
row_num_3 = sht.api.Range('C1').End(Direction.xlDown).Row
d = {}
# Add A column data, player name as key, award = "Ballon d'Or"
for i in range(2, row_num_1):
    d[sht.cells(i, 1).value] = 'Ballon d\'Or'
# Process B column
for i in range(2, row_num_2):
    if sht.cells(i, 2).value in d:
        d[sht.cells(i, 2).value] = d[sht.cells(i, 2).value] + ',Best Player'
    else:
        d[sht.cells(i, 2).value] = 'Best Player'
# Process C column
for i in range(2, row_num_3):
    if sht.cells(i, 3).value in d:
        d[sht.cells(i, 3).value] = d[sht.cells(i, 3).value] + ',Golden Boot'
    else:
        d[sht.cells(i, 3).value] = 'Golden Boot'
# Output results
sht.range('E1').options(transpose=True).value = list(d.keys())
sht.range('F1').options(transpose=True).value = list(d.values())

Running the program outputs results in columns E and F of Figure 8-6.

Application Example 3: Summarize Subtopics of Research Projects

As shown in Figure 8-7, columns A and B contain research project and subtopic data. The task is to summarize subtopics for each project, join them with "|" into a string, and count the number of subtopics.

Document Image

Figure 8-7

Solution idea: This is a combination of Examples 8.5.1 and 8.5.2. Create two dictionaries: one for subtopic names, another for subtopic counts. Refer to previous examples for method details.

[Excel VBA] Sample file path: Samples\ch08\Excel VBA\Summarize Subtopics of Research Projects.xlsm.

code.vba
Sub Test()
    Dim intI As Integer
    Dim d1 As Dictionary   ' Dictionary for subtopic names
    Set d1 = New Dictionary
    Dim d2 As Dictionary   ' Dictionary for subtopic counts
    Set d2 = New Dictionary
    Dim sht As Object
    Set sht = ActiveSheet
    Dim intR As Integer
    Dim strD
    On Error Resume Next
    ' Get original data
    intR = sht.Range("A1").End(xlDown).Row
    For intI = 2 To intR
        strD = sht.Cells(intI, 1).Value
        ' If key exists, append new subtopic name and increase count
        If d1.Exists(strD) Then
            d1(strD) = d1(strD) & "|" & sht.Cells(intI, 2).Value
            d2(strD) = d2(strD) + 1
        Else
            ' Not exist, add new key-value
            d1.Add strD, sht.Cells(intI, 2).Value
            d2.Add strD, 1
        End If
    Next
    ' Output project names
    sht.Range("D2").Resize(d1.Count, 1).Value = _
        Application.WorksheetFunction.Transpose(d1.Keys)
    ' Output subtopic names
    sht.Range("E2").Resize(d1.Count, 1).Value = _
        Application.WorksheetFunction.Transpose(d1.Items)
    ' Output subtopic counts
    sht.Range("F2").Resize(d1.Count, 1).Value = _
        Application.WorksheetFunction.Transpose(d2.Items)
End Sub

Running the program outputs results in columns D–F of Figure 8-7.

[Python] Sample data file path: Samples\ch08\Python\Summarize Subtopics of Research Projects.xlsx, .py file named sam08-03.py.

code.python
class="text-secondary">import xlwings class="text-secondary">as xw
class="text-secondary">from xlwings.constants class="text-secondary">import Direction
class="text-secondary">import os
root = os.getcwd()
app = xw.App(visible=True, add_book=False)
bk = app.books.open(fullname=root + r'\Summarize Subtopics of Research Projects.xlsx', read_only=False)
sht = bk.sheets(1)
row_num = sht.api.Range('A1').End(Direction.xlDown).Row
d1 = {}   # Dict 1: project class="text-secondary">as key, subtopic collection class="text-secondary">as value
d2 = {}   # Dict 2: project class="text-secondary">as key, subtopic count class="text-secondary">as value
for i in range(2, row_num):
    it = sht.cells(i, 1).value
    if it in d1:
        d1[it] = d1[it] + '|' + sht.cells(i, 2).value
        d2[it] = d2[it] + 1
    else:
        d1[it] = sht.cells(i, 2).value
        d2[it] = 1
# Output project names
sht.range('D2').options(transpose=True).value = list(d1.keys())
# Output subtopic names
sht.range('E2').options(transpose=True).value = list(d1.values())
# Output subtopic counts
sht.range('F2').options(transpose=True).value = list(d2.values())

Running the program outputs results in columns D–F of Figure 8-7.