Home Accessibility Courses Twitter The Mouth Facebook Resources Site Map About Us Contact
 
For 2023 (and 2024 ...) - we are now fully retired from IT training.
We have made many, many friends over 25 years of teaching about Python, Tcl, Perl, PHP, Lua, Java, C and C++ - and MySQL, Linux and Solaris/SunOS too. Our training notes are now very much out of date, but due to upward compatability most of our examples remain operational and even relevant ad you are welcome to make us if them "as seen" and at your own risk.

Lisa and I (Graham) now live in what was our training centre in Melksham - happy to meet with former delegates here - but do check ahead before coming round. We are far from inactive - rather, enjoying the times that we are retired but still healthy enough in mind and body to be active!

I am also active in many other area and still look after a lot of web sites - you can find an index ((here))
Tcl - dicts - a tutorial and examples

Dictionaries

At Tcl 8.5, the dict command was added to Tcl.

What is a dictionary

A dict used the same formatting as a list - in other words, it's a string of text (just like every other variable type except an array) which is handled through the same tokeniser / interpreter that's used for the source code of Tcl. However, in the using of the dict command, list members are taken as alternate key / value pairs. In effect, that gives you the capabilities of an array but with the flexibility of handling your data as a pure string too - in the right circumstances, it's the best of both worlds.

For example, I can set up a dictionary or a list as follows:

  set demo {Anne Jones Bill Brown Charlotte Steeple Dennis {The Menace} Enid Blyton
  Fred Dibnah Gwynn Grimm Henry Eighth Isobel Quietly}


and access a member via its key with dict:

  set surname [dict get $demo Enid]
  puts $surname


which runs like this:

  wizard:textra graham$ tclsh dict1
  Blyton
  wizard:textra graham$


[source link]

and equally I can access members via position (a list):

  set surname [lindex $demo 9]
  puts $surname


which runs like this:

  wizard:textra graham$ tclsh dict2
  Blyton
  wizard:textra graham$


[source link]

Iterating through a dictionary

dict keys will return you a list of keys (very useful) and dict values will return you a list of values - rarely what you want. Here's dict keys in use:

  set demo {Anne Jones Bill Brown Charlotte Steeple Dennis {The Menace} Enid Blyton
  Fred Dibnah Gwynn Grimm Henry Eighth Isobel Quietly}
  
  foreach item [dict keys $demo] {
    set val [dict get $demo $item]
    puts "We have $item with a value $val"
    }


[source link]

And the sample output:

  wizard:textra graham$ tclsh dict3
  We have Anne with a value Jones
  We have Bill with a value Brown
  We have Charlotte with a value Steeple
  We have Dennis with a value The Menace
  We have Enid with a value Blyton
  We have Fred with a value Dibnah
  We have Gwynn with a value Grimm
  We have Henry with a value Eighth
  We have Isobel with a value Quietly
  wizard:textra graham$


There is also a dict for command which lets you iterate through key, value pairs and run a block of code on each pair - so it's actually a new loop:

  set demo {Anne Jones Bill Brown Charlotte Steeple Dennis {The Menace} Enid Blyton
  Fred Dibnah Gwynn Grimm Henry Eighth Isobel Quietly}
  dict for {thekey theval} $demo {
  puts "We have $thekey with a value $theval"
  }


(example dict4) which produces the same output as the example above.

[source link]

dictionary manipulation commands

* You can pass a dict into a proc without using upvar!

  proc timetable {type schedule} {
    puts "\n----------> $type"
    dict for {where when} $schedule {
      puts [format "%-25s %11s" $where $when]
      }
    }
  
  set mydata [dict create "Cardiff Central" 06:28 Newport 06:42 \
      "Severn Tunnel Junction" 06:53 Pilning 07:03 Patchway 07:06]
  dict lappend mydata {Filton Abbey Wood} 07:09
  set moredata [dict create "Bristol Temple Meads" dunno Bath\ Spa 07:35 \
      Bradford-on-Avon 07:47 Trowbridge 07:53 Westbury 08:00]
  
  # Merge two dictionaries
  set allway [dict merge $mydata $moredata]
  
  timetable original $allway
  
  # lappend only adds ONE item - so this has to be 2 separate commands
  dict lappend allway Warminster 08:09
  dict lappend allway Salisbury 08:32
  
  # Add to existing value within the dictionary
  dict append allway Westbury -08:01
  
  # Remove an item from the dictionary
  set allway [dict remove $allway Pilning]
  
  # Replace a value
  set allway [dict replace $allway {Bristol Temple Meads} 07:22]
  
  timetable modified $allway
  
  # search by value and return a shorter dict
  set before_8 [dict filter $allway value {0[0-7]*} ]
  
  timetable "before 8 a.m." $before_8
  
  # How many items?
  set sz [dict size $before_8]
  puts "There are $sz items in that dict"


[source link]

Let's see what I have used that's new:

dict create - create a new dictionary
dict append - append a string to a value in a dictionary
dict lappend - add a new key, value pair to a dictionary
dict merge - concatenate two dictionaries, but remove duplicate keys
dict remove - remove a pair based on its key
dict replace - replace a value based on its key
dict filter - return a small dictionary based on a match to a key or a value
dict size - tell me how many pairs there are in a dictionary

It runs like this:

  wizard:textra graham$ tclsh dicdem
  
  ----------> original
  Cardiff Central 06:28
  Newport 06:42
  Severn Tunnel Junction 06:53
  Pilning 07:03
  Patchway 07:06
  Filton Abbey Wood 07:09
  Bristol Temple Meads dunno
  Bath Spa 07:35
  Bradford-on-Avon 07:47
  Trowbridge 07:53
  Westbury 08:00
  
  ----------> modified
  Cardiff Central 06:28
  Newport 06:42
  Severn Tunnel Junction 06:53
  Patchway 07:06
  Filton Abbey Wood 07:09
  Bristol Temple Meads 07:22
  Bath Spa 07:35
  Bradford-on-Avon 07:47
  Trowbridge 07:53
  Westbury 08:00-08:01
  Warminster 08:09
  Salisbury 08:32
  
  ----------> before 8 a.m.
  Cardiff Central 06:28
  Newport 06:42
  Severn Tunnel Junction 06:53
  Patchway 07:06
  Filton Abbey Wood 07:09
  Bristol Temple Meads 07:22
  Bath Spa 07:35
  Bradford-on-Avon 07:47
  Trowbridge 07:53
  There are 9 items in that dict
  wizard:textra graham$


To more or less complete the story, you also have

dict incr - to increment a value within a dict. Very useful indeed for counters
dict info - information string about the dict
dict exists - to check whether a key exists

Nested Dictionaries

Just as you can have lists within lists, you can have dicts within dicts. And indeed some of the dict subcommands actually provide extra support for this. Here's an example:

  dict set course Tcl Learning 4
  dict set course Tcl Programming 3
  dict set course Perl Learning 5
  dict set course Perl Programming 5
  dict set course Perl Advanced 3
  dict set course Python Learning 4
  dict set course Python Programming 3
  
  puts $course
  
  dict for {language levels} $course {
    puts "$language courses"
    dict with levels {
      puts "--- First level $Learning"
      puts "--- Second level $Programming"
      if {[dict exists $course $language Advanced]} {
        puts "--- Third level $Advanced"
      } else {
        puts "--- Third level not offered"
      }
    }
  }


[source link]

Which runs as follows:

  wizard:textra graham$ tclsh nested
  Tcl {Learning 4 Programming 3} Perl {Learning 5 Programming 5 Advanced 3} Python {Learning 4 Programming 3}
  Tcl courses
  --- First level 4
  --- Second level 3
  --- Third level not offered
  Perl courses
  --- First level 5
  --- Second level 5
  --- Third level 3
  Python courses
  --- First level 4
  --- Second level 3
  --- Third level not offered
  wizard:textra graham$

(written 2012-02-14, updated 2012-02-18)

 
Associated topics are indexed as below, or enter http://melksh.am/nnnn for individual articles
T208 - Tcl/Tk - Arrays and dicts
  [122] Passing arrays to procs in Tcl - (2004-11-18)
  [779] The fragility of pancakes - and better structures - (2006-06-26)
  [1282] Stringing together Tcl scripts - (2007-07-29)
  [1283] Generating traffic for network testing - (2007-07-29)
  [1405] Sorting in Tcl - lists and arrays - (2007-10-24)
  [1427] Arrays in Tcl - a demonstration - (2007-11-10)
  [1614] When an array is not an array - (2008-04-17)
  [2466] Tcl - passing arrays and strings in and back out of procs - (2009-10-22)
  [3192] Tcl - Some example of HOW TO in handling data files and formats - (2011-03-04)
  [3415] User defined sorting and other uses of callbacks in Tcl and Tk - (2011-09-02)
  [3582] Tcl collections - lists, dicts and array - (2012-01-16)
  [3638] Sorting dicts and arrays in Tcl - (2012-03-04)


Back to
Keeping Business Local. But is that realistic?
Previous and next
or
Horse's mouth home
Forward to
Historic documents for Wiltshire
Some other Articles
lists and struct::list in Tcl - Introduction to struct::list and examples
The fileutil package and a list of file system commands in Tcl
Bus top - colours of London
Historic documents for Wiltshire
Tcl - dicts - a tutorial and examples
Keeping Business Local. But is that realistic?
Help to get online in Melksham
A customer thanks Well House Manor
Training to do a job, or training to pass an exam?
How do classes relate to each other? Associated Classes
4759 posts, page by page
Link to page ... 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, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96 at 50 posts per page


This is a page archived from The Horse's Mouth at http://www.wellho.net/horse/ - the diary and writings of Graham Ellis. Every attempt was made to provide current information at the time the page was written, but things do move forward in our business - new software releases, price changes, new techniques. Please check back via our main site for current courses, prices, versions, etc - any mention of a price in "The Horse's Mouth" cannot be taken as an offer to supply at that price.

Link to Ezine home page (for reading).
Link to Blogging home page (to add comments).

You can Add a comment or ranking to this page

© WELL HOUSE CONSULTANTS LTD., 2024: 48 Spa Road • Melksham, Wiltshire • United Kingdom • SN12 7NY
PH: 01144 1225 708225 • EMAIL: info@wellho.net • WEB: http://www.wellho.net • SKYPE: wellho

PAGE: http://www.wellho.net/mouth/3614_Tcl ... mples.html • PAGE BUILT: Sun Oct 11 16:07:41 2020 • BUILD SYSTEM: JelliaJamb