python types in list during comprehension
Question: I have a sql query string such as the following:

    
    
    intro text,
    id int,
    description varchar(50)
    

I am trying to create a string of types, with the goal of finding pieces of
text that do not match the types defined in the sql schema. The way I am
extracting the types from the sql text is as follows:

    
    
    types = [re.sub('[^a-zA-Z]','',x.split()[1]) for x in schema] 
    types = [re.sub('varchar',types.StringType,x) for x in types]
    types = [re.sub('text',types.StringType,x) for x in types]
    types = [re.sub('bigint',types.IntType,x) for x in types]
    types = [re.sub('decimal',types.IntType,x) for x in types]
    

However the interpreter complains that

    
    
    types = [re.sub('varchar',types.StringTypes,x) for x in types]
    AttributeError: 'list' object has no attribute 'StringTypes'
    

A SSCCE

With the following schema file

    
    
    intro text,
    id int,
    description varchar(50)
    

and code (note, with fix as suggested by oscar below, but now with other
error)

    
    
    import csv
    import sys
    import re
    import types
    
    sch = open(sys.argv[1], "rb")
    
    #---------------------------------   
    # read schema
    #---------------------------------     
    with sch as f:
        schema = f.read().splitlines()
    
    #---------------------------------    
    # extract schema types
    #---------------------------------  
    
    foundtypes = [re.sub('[^a-zA-Z]','',x.split()[1]) for x in schema] 
    foundtypes = [re.sub('varchar',str,x) for x in foundtypes]
    foundtypes = [re.sub('text',str,x) for x in foundtypes]
    foundtypes = [re.sub('int',int,x) for x in foundtypes]
    foundtypes = [re.sub('bigint',int,x) for x in foundtypes]
    foundtypes = [re.sub('decimal',int,x) for x in foundtypes]
    
    print foundtypes
    

I am using Python 2.7.5

thank you


Answer: You overwrote the binding (see: [variable
shadowing](http://en.wikipedia.org/wiki/Variable_shadowing)) to the `types`
[module](https://docs.python.org/2/library/types.html), in this line:

    
    
    types = [re.sub('[^a-zA-Z]','',x.split()[1]) for x in schema]
    

After that, `types` is no longer pointing to the module, but to a list. Just
use another name in all the assignments:

    
    
    my_types = [re.sub('[^a-zA-Z]','',x.split()[1]) for x in schema] 
    my_types = [re.sub('varchar',types.StringType,x) for x in my_types]
    my_types = [re.sub('text',types.StringType,x) for x in my_types]
    my_types = [re.sub('bigint',types.IntType,x) for x in my_types]
    my_types = [re.sub('decimal',types.IntType,x) for x in my_types]
    

**UPDATE**

I think you overdesigned the solution, except for the first line this is not a
good fit for using regular expressions. A simple `if-elif-else` will work just
fine:

    
    
    def transform(typestr):
        if typestr in ('varchar', 'text'):
            return types.StringType
        elif typestr in ('int', 'bigint', 'decimal'):
            return types.IntType
        else:
            return None
    
    my_types = [re.sub(r'[^a-zA-Z]', '', x.split()[1]) for x in schema] 
    [transform(x) for x in my_types]
    => [<type 'str'>, <type 'int'>, <type 'str'>]
    

