[Tutor] slicing nested lists/dicts/tuples

Brian van den Broek bvande at po-box.mcgill.ca
Sat Jul 2 23:53:04 CEST 2005

Luis N said unto the world upon 02/07/2005 07:51:
> On 7/2/05, Luis N <tegmine at gmail.com> wrote:
> Umm, sorry, I meant:
> d[desc[x]] = exec("""'vw[%s].desc[%s]'""" % (r,x ))
> ------------------------------------------------------------------------
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> http://mail.python.org/mailman/listinfo/tutor

Hi Luis,

I don't know anything about metakit, and thus I don't know anything 
about the details of the data structure from:

> vw = db.getas('contacts[first:S,last:S,phone:S,email:S,notes:S]')

So, I can't manifest exactly how it would work, but unless there is 
some odd constraint imposed by metakit, you don't need to (and 
probably shouldn't) use exec or eval.

It *looks* to me like you are trying to take some object returned by a 
metakit method and use it to build a Python dict. I'm sure I don't 
have the details of your task right, but here is some code that does a 
similar thing without eval or exec:

 >>> desc = ('first', 'last', 'email')
 >>> class Person(object):
... 	def __init__(self, first, last, email):
... 		self.first = first
... 		self.last = last
... 		self.email = email
 >>> bob = Person('Bob', 'Jones', 'bob at theinternet.org')
 >>> jane = Person('Jane', 'Best', 'jane at earth.org')
 >>> persons = (jane, bob)
 >>> # persons is intended to serve a similar role as your vw. It is a
 >>> # sequence of objects, from which I will build a dict, without
 >>> # eval or exec.
 >>> persons_dict = {}
 >>> def update(target_dict, object_tuple, attribs):
... 	for o in object_tuple:
... 		temp = {}
... 		for a in attribs:
... 			temp[a] = o.__getattribute__(a)
... 		target_dict[o.__getattribute__(attribs[0])] = temp
... 	return target_dict
 >>> persons_dict = update(persons_dict, persons, desc)
 >>> persons_dict
{'Jane': {'last': 'Best', 'email': 'jane at earth.org', 'first': 'Jane'}, 
'Bob': {'last': 'Jones', 'email': 'bob at theinternet.org', 'first': 'Bob'}}

Obviously this won't be exactly what you need, but I hope it can give 
you an idea of how to make what you *do* need.

Why am I down on eval and exec? Well,

 >>> exec("print 6")

is harmless. But, running:


would suck :-)

Similar nastiness can happen with eval:
 >>> def f(): print 6
 >>> eval('f()')

Make f() an evil function, and it'll all end in tears :-)

So, they are considered a security risk. You may well trust your data 
drawn from metakit in this instance. But, I think it is a good habit 
to avoid them when they can be avoided.

I hope I've helped at least some. Best,

Brian vdB

More information about the Tutor mailing list