Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access a dictionary as a list

I have a data source which is best modeled with a dictionary (it is a collection of key=value pairs). For a specific visualization purpose, I need to provide a list-like data access interface (in addition to the regular dictionary interface), meaning that you should be able to do the following:

data["mykey"] # returns the associated value
data[12][0] # returns the 13th key in the dictionary
data[12][1] # returns the 13th value in the dictionary

I cannot find an appropriate facade implementation - if I store the indices as the dictionary key:

data[12] = ("mykey", "myval")

I can easily solve the last two cases, but I loose the ability to do the first. If I store data like

data["mykey"] = "myval"

I have to enumerate all keys and values in a temporary list before I can return elements.

Notice that all this implementations assume I am using an OrderedDict.

How would you provide both interfaces?

If you are curious, this is for creating a PyQt QAbstractTableModel where the underlying data container is a dictionary.

Thanks.

like image 978
Escualo Avatar asked Oct 10 '22 17:10

Escualo


1 Answers

I have to do the same thing to represent data in a ListCtrl that needs to be accessible by a key rather than by index at times (so that it does not have to be searched if I get an arbitrary value to locate). If you have a list of dictionaries, the best I found was to create another dictionary with references to the same items, but accessible by key. This becomes my data load in method:

  def SetData(self, cols, data):
    for idx, row in enumerate(data):
      item = dict((k, v.rstrip() if hasattr(v, 'rstrip') else v) for k, v in zip(cols, row))

      self.data[idx] = item

      self.byid[row[0]] = item

So I have a list of dictionaries accessible in self.data, and then another dictionary in self.byid that keeps the same items, but by the id column (column 0 in my rows in this case). When I need to update, as long as I get an ID, I can call self.byid[id][field] = newval. Because everything in Python is a pointer (reference), changing the value of the dictionary stored in self.byid is reflected in the list of dictionaries stored in self.data. Works like a charm.

like image 128
g.d.d.c Avatar answered Oct 14 '22 04:10

g.d.d.c