Kavit Shah
Kavit Shah

Reputation: 505

Creating a table in python

I want to build a table in python with three columns and later on fetch the values as necessary. I am thinking dictionaries are the best way to do it, which has key mapping to two values.

|column1 |  column 2     | column 3   | 

|  MAC   |  PORT NUMBER  |    DPID    |

|  Key   |  Value 1      | Value 2    |

proposed way :

// define a global learning table globe_learning_table = defaultdict(set)

// add port number and dpid of a switch based on its MAC address as a key // packet.src will give you MAC address in this case globe_learning_table[packet.src].add(event.port) globe_learning_table[packet.src].add(dpid_to_str(connection.dpid))

// getting value of DPID based on its MAC address globe_learning_table[packket.src][????]

I am not sure if one key points to two values how can I get the particular value associated with that key.

I am open to use any another data structure as well, if it can build this dynamic table and give me the particular values when necessary.

Upvotes: 4

Views: 1066

Answers (5)

Jim Dennis
Jim Dennis

Reputation: 17500

Why a dictionary? Why not a list of named tuples, or a collection (list, dictionary) of objects from some class which you define (with attributes for each column)?

What's wrong with:

class myRowObj(object):
    def __init__(self, mac, port, dpid):
        self.mac  = mac
        self.port = port
        self.dpid  = dpid


myTable = list()
for each in some_inputs:
    myTable.append(myRowObj(*each.split())

... or something like that?

(Note: myTable can be a list, or a dictionary or whatever is suitable to your needs. Obviously if it's a dictionary then you have to ask what sort of key you'll use to access these "rows").

The advantage of this approach is that your "row objects" (which you'd name in some way that made more sense to your application domain) can implement whatever semantics you choose. These objects can validate and convert any values supplied at instantiation, compute any derived values, etc. You can also define a string and code representations of your object (implicit conversions for when one of your rows is used as a string or in certain types of development and debugging or serialization (_str_ and _repr_ special methods, for example).

The named tuples (added in Python 2.6) are a sort of lightweight object class which can offer some performance advantages and lighter memory footprint over normal custom classes (for situations where you only want the named fields without binding custom methods to these objects, for example).

Upvotes: 3

Todd
Todd

Reputation: 6169

Another option to keep in mind is an in-memory SQLite table. See the Python SQLite docs for a basic example:

11.13. sqlite3 — DB-API 2.0 interface for SQLite databases — Python v2.7.5 documentation http://docs.python.org/2/library/sqlite3.html

Upvotes: 1

JosefAssad
JosefAssad

Reputation: 4128

I think you're getting two distinct objectives mixed up. You want a representative data structure, and (as I read it) you want to print it in a readable form. What gets printed as a table is not stored internally in the computer in two dimensions; the table presentation is a visual metaphor.

Assuming I'm right about what you want to accomplish, the way I'd go about it is by a) keeping it simple and b) using the right modules to save effort.

The simplest data structure that correctly represents your information is in my opinion a dictionary within a dictionary. Like this:

foo = {'00:00:00:00:00:00': {'port':22, 'dpid':42},
       '00:00:00:00:00:01': {'port':23, 'dpid':43}}

The best module I have found for quick and dirty table printing is prettytable. Your code would look something like this:

foo = {'00:00:00:00:00:00': {'port':22, 'dpid':42},
       '00:00:00:00:00:01': {'port':23, 'dpid':43}}

t = PrettyTable(['MAC', 'Port', 'dpid'])
for row in foo:
    t.add_row([row, foo[row]['port'], foo[row]['dpid']])

print t

Upvotes: 0

dav
dav

Reputation: 1219

Something like this perhaps?

>>> global_learning_table = collections.defaultdict(PortDpidPair)
>>> PortDpidPair = collections.namedtuple("PortDpidPair", ["port", "dpid"])
>>> global_learning_table = collections.defaultdict(collections.namedtuple('PortDpidPair', ['port', 'dpid']))
>>> global_learning_table["ff:" * 7 + "ff"] = PortDpidPair(80, 1234)
>>> global_learning_table
defaultdict(<class '__main__.PortDpidPair'>, {'ff:ff:ff:ff:ff:ff:ff:ff': PortDpidPair(port=80, dpid=1234)})
>>>

Named tuples might be appropriate for each row, but depending on how large this table is going to be, you may be better off with a sqlite db or something similar.

Upvotes: 3

Kyle
Kyle

Reputation: 893

If it is small enough to store in memory and you want it to be a data structure, you could create an class that contains Values 1 & 2 and use that as the value for your dictionary mapping.

However, as Mr E pointed out, it is probably better design to use a database to store the information and retrieve as necessary from there. This will likely not result in significant performance loss.

Upvotes: 1

Related Questions