0

I am trying to implement a customized automata where the transition table looks like:

enter image description here

The table is dynamic i.e. the column heading, row name, and data at every cell can be determined at run time. The column name and row name are also necessary.

I tried this code

table = []
table.append(["A",[0,["B",2],["C1",2]],[1,["C1",1]]])
table.append(["B",[0,["C",1]],[1,["C2",1]]])
table.append(["C",[0,["C1",1]],[1,["C2",1]]])

but I am unable to access the individual item in the cell i.e. B or 2 from B:2 etc. Then I tried

row = ["A","B","C","C1","C2"]
col = [0,1]
table = [] 
table.append([[["B",2],["C1",2]],["C1",1]])
table.append([["C",1],["C2",1]])
table.append([["C1",1],["C2",1]])

print(table[0][0][0][0])

Now, I can access the individual item (B in the above case) but I am lost with the four subscript. Specially, when I do not know the depth of the list in advance. Need to get some help to do it in some easy way. Being a novice, I will appreciate some explanation to the pythonic code.

Update: This is Non-deterministic Finite Automata. I tried the automaton package but they are not solving my problem. Following the solution of Tadhg-Mcdonald-Jensen, it give the correct out put for the first row (A) in the table but an error message for second row (B). Here is the code

table = {}
table["A"] = {0: {"B":2, "C1":2}, 1: {"C1":1}}
table["B"] = {0: {"C":1},         1: {"C2",1}}
table["C"] = {0: {"C1":1},        1: {"C2",1}}

for key,value in table["A"][0].items():  \\ok treated as dictionary (1)
    print(key, value, sep="\t")        
for key,value in table["A"][1].items():  \\ok treated as dictionary (2)
    print(key, value, sep="\t")          
for key,value in table["B"][0].items():  \\ok treated as dictionary (3)
    print(key, value, sep="\t")          
for key,value in table["B"][1].items():  \\wrong: why treated as set? Although same as (2)
    print(key, value, sep="\t")          \\Error message: AttributeError: 'set' object has no attribute 'items' 

The output is

B   2
C1  2 
C1  1
C   1
Traceback (most recent call last):
  File "C:/Users/Abrar/Google Drive/Tourism Project/Python Projects/nestedLists.py", line 17, in <module>
for key,value in table["B"][1].items():
AttributeError: 'set' object has no attribute 'items'
Dr. Abrar
  • 327
  • 2
  • 5
  • 17
  • 2
    I would suggest you to look into pandas (http://pandas.pydata.org/). It's built for specifically handling tabular data and you will be able to access elements very easily using index and column names. – Ankur Ankan Oct 24 '17 at 21:48
  • I tried but having same confusion of accessing the multilevel nested elements. I am giving it another try. Thanks – Dr. Abrar Oct 24 '17 at 21:57
  • PANDAS is perfectly happy to handle nested lists within a table. You just have to make sure you feed it the proper diet of punctuation. – Prune Oct 24 '17 at 22:07
  • The errors you show at the end of your code have to do with these entries: `{"C2",1}`. You want `{"C2": 1}` (with a colon instead of a comma). – Blckknght Oct 25 '17 at 06:29
  • **THANK YOU so much** – Dr. Abrar Oct 25 '17 at 06:35

1 Answers1

2

Pandas is great at doing tables but you could also move to dictionaries, either way, list is not the data structure you want.

table = {}
table["A"] = {0: {"B":2, "C1":2}, 1: {"C1":1}}
table["B"] = {0: {"C":1},         1: {"C2":1}}
table["C"] = {0: {"C1":1},        1: {"C2":1}}

Then table["A"][0] will give you the first element, each element will have one or more entries, if you wanted to iterate over the entries you can do for key,value in table["A"][0].items()

Or to iterate over the entire table you could use 3 nested for loops:

#do_stuff = print
for row, line in table.items():
    #each row in the table, row will go through ("A", "B", "C")
    for column, cell in line.items():
        #each cell in the row, column will go through (0, 1)
        for label, value in cell.items(): 
            #each entry in cell, most only have one entry except table["A"][0]
            do_stuff(row, column, label, value)

To be honest I don't understand what the table represents so I can't give you specific advice but I think this would at least be a clearer data structure.

Tadhg McDonald-Jensen
  • 20,699
  • 5
  • 35
  • 59
  • You have a typo on both of the `C2` entries. You need colons instead of commas: `{"C2": 1}`. With a comma you get a set instead of a dictionary. – Blckknght Oct 25 '17 at 06:30
  • Thank you so much Blcknght. I am novice. – Dr. Abrar Oct 25 '17 at 06:34
  • @Abrar next time an answer gives you issues please comment on the answer, that way I'd get a notification that you asked a clarifying question and can respond with help. :) – Tadhg McDonald-Jensen Oct 28 '17 at 16:26
  • @TadhgMcDonald-Jensen Thank you so much for updated answer. You saved my days by giving the iterative solution. Can you tell me that how can I update the table if I want want to find and key in the table and increment its associated values. Like for B, i need to increment :2 to 3 and if the key in not present in the table I will add {'New':1} to corresponding key. Is it okay to ask it here or I need to ask another question? Thanks for your guidance. – Dr. Abrar Oct 29 '17 at 22:19
  • @Abrar to add entries to a cell look at [this question](https://stackoverflow.com/questions/473099/check-if-a-given-key-already-exists-in-a-dictionary-and-increment-it). And know that [`Counter`](https://docs.python.org/3/library/collections.html#collections.Counter) works like `defaultdict(int)`. So you'd have something like `table['A'] = {0:Counter(B=2, C1=2), 1:Counter(C1=1)}`. If that question doesn't solve your issue then you would post a new question. :) – Tadhg McDonald-Jensen Nov 01 '17 at 12:17
  • @TadhgMcDonald-Jensen Thank you so much.The issue is resolved :) – Dr. Abrar Nov 02 '17 at 04:40