Question about locals()

J. Cliff Dyer jcd at sdf.lonestar.org
Fri May 22 11:44:13 EDT 2009


Top-posting corrected.

On Fri, 2009-05-22 at 10:00 -0500, Gökhan SEVER wrote:

> On Fri, May 22, 2009 at 9:43 AM, David Robinow <drobinow at gmail.com>
> wrote:
>         On Fri, May 22, 2009 at 10:27 AM, Gökhan SEVER
>         <gokhansever at gmail.com> wrote:
>         ...
>         > serialc = np.loadtxt(sys.argv[1], skiprows=skiprows).T
>         > for i in range(20):
>         >     locals()['serialc_bin' + str(i+1)] = serialc[i+4]
>         >
>         > I don't know easier way than using locals() to construct
>         variable-like
>         > identities in my program.
>         
>         
>         I don't either.  I also don't know why you feel you need to
>         construct
>         variable-like identities.
>         Why is:
>          serialc_bin1
>         better than
>          serialc_bin[0]
>         or, for that matter,
>          serialc[4]
>         
>         ???
>         
>         --
>         http://mail.python.org/mailman/listinfo/python-list
>         

> Because in this case serialc is an numpy array. Since loadtxt returns
> a numpy-array. Furthermore 
> 
> locals()['serialc_bin' + str(i+1)]  creates a dictionary key (that's
> what I use the term "variable-like") serialc_bin1, serialc_bin2, ...
> not serialc_bin[0] with indexes. 
> 
> 
> Gökhan
> 
> 

I'm not sure why dictionary keys are better than indexes in your
example, especially as they're being created by coercing integers to
strings.  However, that's your business.  But why not just create your
own dictionary.  Then you can pass the results around easily as a group
or one at a time, and you don't have to mess in locals() (which isn't
supposed to be messed in).  It also gives you more flexibility as to how
you name your entries:

d = {}

You can use the same indexes you're using now:

d['serialc_bin' + str(i+1)] = serialc[i+4]

or you can keep the integerness of i by using tuples as keys (thus
preserving sort order across your keys):

d[('serialc_bin', i+1)] = serialc[i+4]

or you can use the integer as a key by itself (yes!  It looks like
you're accessing a list, but it's actually a dict with integer keys):

d[i+1] = serialc[i+4]

Or you can use a dict with a more descriptive name and the last above
solution gains the readability of your initial solution:

serialc_bin = {}
serialc_bin[i+1] = serialc[i+4]

Finally, if there's more you want to do with these numbers, you can
create a class to hold them.  Then as you need to, you can add methods
to it to implement the behavior you're looking for.

class MyCollection(object):
    """Untested code"""

    def __init__(self):
        self._store = {}

    def __getitem__(self, item):
        return self._store[item]

    def __setitem__(self, item, value):
        self._store[item] = value

    def __delitem__(self, item):
        del(self._store[item])

    def sum(self):
        total = 0
        for value in self._store.values():
            total += value
        return value

serialc_bin = MyCollection()
for i, value in enumerate(serialc):
    serialc_bin[i+1] = value
print serialc_bin.sum()

Any one of these seems like a better idea to me than trying to pollute
your local namespace with an unknown number of variables.  You have a
collection of objects.  It makes sense to store them in one of python's
collection types, or create an object of your own to store them.

Cheers,
Cliff





More information about the Python-list mailing list