Geometry table for use in regexes I have been teaching myself Python 3. I watched a video on YouTube entitled "stop writing classes". The Gtable class doesn't even have an init function, so I can't help but wonder if I should have done something different. Also as someone teaching themselves a language for the first time I would really appreciate any critique on how to write the code more efficiently, as well as any anti-idioms unintentionally used. Specifically I feel like there was probably a better way to generate the dictionaries, but especially with the first one I was having trouble writing a comprehension.

##input file text
##|HAAS T|TARGET T|XGEOM|ZGEOM
##$T0101$T0101$X22.960$Z20.0$
##$T0202$T0606$X32.425$Z7.376$
##$T0303$T0404$X30.588$Z15.620$
##$T0404$T0202$X22.367$Z18.549$
##$T0505$T0808$X33.291$Z8.197$

class GeometryTable(dict):
    "create a geometry table from a file for use in regexes"
    def __init__(self):
        self.d={}
    def create(self,location):
        f=open(location,'r')
        tablestring=f.read()
        f.close()
        tablelist=[]
        tablelist=tablestring.split('$')
        #delete unecessary data from list
        tablelist.pop(0)
        tablelist=[item for item in tablelist if item!='\n']
        #create a dictionary
        count=0
        keylist=[]
        valuelist=[]
        while count&lt;len(tablelist):
            keylist.append(tablelist[count])
            valuelist.append([tablelist[count+1],tablelist[count+2],tablelist[count+3]])
            count+=4
        self.d=dict(zip(keylist,valuelist))
    def xval(self,string):
        if string in self.d:
            return (self.d[string][1])
        else:return(r"X20.0")
    def zval(self,string):
        if string in self.d:
            return (self.d[string][2])
        else:return(r"Z20.0")
    def tval(self,string):
        if string in self.d:
            return (self.d[string][0])
        else:return(r"T2020")
    def report(self,string):
        if string in self.d:
            return (self.d[string])
        else:return(r"(no value)")


class GTable(GeometryTable):
    """for replacing geometries that were given
       default values before this program was created"""
    def load(self,location):
        GeometryTable.load(self,location)
        b=self.__dict__["d"].values()
        redict={x[0]:x for x in b}
        self.d=redict

##output dictionaries for regular expressions
##&gt;&gt;&gt; test.d
##{'T0101': ['T0101', 'X22.960', 'Z20.0'],
## 'T0202': ['T0606', 'X32.425', 'Z7.376'],
## 'T0303': ['T0404', 'X30.588', 'Z15.620'],
## 'T0404': ['T0202', 'X22.367', 'Z18.549'],
## 'T0505': ['T0808', 'X33.291', 'Z8.197']}
So there are a few improvements that I can see in your code, mainly in the create function.



When reading a file, use the with keyword. This will open the file and, once the program leaves that scope, the file will automatically be closed.

I would recommend changing how you read the file. From what I can tell, each line will be its own key in your dict. So instead of reading the entire file in one statement, I would recommend reading line-by-line.

By making the changes mentioned above, when we split the input by $, we get unnecessary values in the first and last index of the resulting list. To fix this, we can use list slicing. By using the notation list[start:end], where start specifies the first index you want included and stop specifies the first index you want excluded, we can remove the first and last indices.

Finally, when creating a dict you can assign a key-value pair simply by using the syntax:

dict[key] = value


Bringing all of these suggestions together, here is my version of your create function:

def create(self, location):
    # Once this block of code finishes, f will close.
    with open(location, 'r') as f:
        # Reads the file line-by-line
        for line in f:
            # Split the data and remove the first and last indices
            data = line.split('$')[1:-1]

            # Assign the key-value pair to the dict
            self.d[data[0]] = data[1:]




As a final aside, look over PEP8. PEP8 is the official Python style guide. Following those conventions (especially underscores in variable names, so table_string instead of tablestring) will help your code look and feel more Pythonic.