how to safely extract dict values

D

David Zaret

i have a dict with a particular key - the values for this key will be
None, one valid scalar, or a list:

{mykey, None}
{mykey, "foo"}
{mykey, ["bar", "baz"]}

let's ignore the None case - in the case of the one or many values, i
want to suck the values into a list. here's one way to do this:

if mydict.has_key(mykey):
vals=[]
_v = mydict[mykey]
if isinstance(_v, types.ListType):
vals.extend(_v)
else:
vals.append(_v)
# now we can safely iterate through acts
for val in vals:
.....


my way is ugly. what's a better way?

thanks,

---- dz
 
P

Paul Rubin

David Zaret said:
my way is ugly. what's a better way?

Untested:

for key in mydict:
if isinstance(mydict[key], list):
vals.extend(mydict[key])
else:
vals.append(mydict[key])
 
B

Bruno Desthuilliers

Paul said:
David Zaret said:
my way is ugly. what's a better way?

Untested:

for key in mydict:
if isinstance(mydict[key], list):
vals.extend(mydict[key])
else:
vals.append(mydict[key])

Too much useless lookup IMHO...

vals = []
for k, v in mydict.items():
if isinstance(v, list):
vals.extend(v)
else:
vals.append(v)

!-)

But this is not that different from what the OP found so ugly...
 
A

Amit Khemka

i have a dict with a particular key - the values for this key will be
None, one valid scalar, or a list:

{mykey, None}
{mykey, "foo"}
{mykey, ["bar", "baz"]}

let's ignore the None case - in the case of the one or many values, i
want to suck the values into a list. here's one way to do this:

if mydict.has_key(mykey):
vals=[]
_v = mydict[mykey]
if isinstance(_v, types.ListType):
vals.extend(_v)
else:
vals.append(_v)
# now we can safely iterate through acts
for val in vals:
.....

how about:

vals = []
for val in mydict.values():
try: vals.extend(val)
except: vals.append(val)

cheers,
amit.



--
 
B

Bruno Desthuilliers

David said:
i have a dict with a particular key - the values for this key will be
None, one valid scalar, or a list:

{mykey, None}
{mykey, "foo"}
{mykey, ["bar", "baz"]}

let's ignore the None case - in the case of the one or many values, i
want to suck the values into a list. here's one way to do this:

if mydict.has_key(mykey):
vals=[]
_v = mydict[mykey]
if isinstance(_v, types.ListType):
vals.extend(_v)
else:
vals.append(_v)
# now we can safely iterate through acts
for val in vals:
.....


my way is ugly. what's a better way?

If you have control over the dict's creation and 'filling', you may want
to handle the case there - eventually using a custom dict-like object
that stores everything (but None) in lists. The implementation code for
this object will not be less ugly than the one above, but at least
ugliness will be hidden away !-)

Else, you can shorten the code a bit (NB : ignoring the 'None' case...):

v = d[k]
v = ([v], v)[isinstance(v, list)]

And this can be hidden away in a function:

def get_as_list(d, k):
v = d[k]
return ([v], v)[isinstance(v, list)]

vals = get_as_list(mydict, mykey)


I don't like using isinstance() tests too much, but it depends on the
context...

HTH
 
P

Paul Rubin

Bruno Desthuilliers said:
Too much useless lookup IMHO...

Actually, you, me, and Amit all mis-read David's original exapmle.
What he really wanted was (let's see if I get it right this time):

if mykey in mydict:
v = mydict[mykey]
if not isinstance(v, list):
v = [v]
for val in v: ...
 
B

Bruno Desthuilliers

Amit said:
i have a dict with a particular key - the values for this key will be
None, one valid scalar, or a list:

{mykey, None}
{mykey, "foo"}
{mykey, ["bar", "baz"]}

let's ignore the None case - in the case of the one or many values, i
want to suck the values into a list. here's one way to do this:

if mydict.has_key(mykey):
vals=[]
_v = mydict[mykey]
if isinstance(_v, types.ListType):
vals.extend(_v)
else:
vals.append(_v)
# now we can safely iterate through acts
for val in vals:
.....

how about:

vals = []
for val in mydict.values():
try: vals.extend(val)
except: vals.append(val)
l = []
l.extend((1, 2))
l [1, 2]
l.extend('ab')
l [1, 2, 'a', 'b']
 
D

David Zaret

thanks for the many responses.

i have zero control over the dict. in practice, i'm using turbogears
which is "automatically" populating the result dict with zero-to-many
choices from a generated list of HTML checkboxes. the user can select
none, one, or many, and submit. cherrypy packs the **kwargs arg full of
the selection, as i described in my op.

using a try/exception case to switch between append and extend will not
work. the scalar, coming back as a string, can certainly be iterated
and i'll end up with a bunch of characters in my list.

i like what's posted below - that's more compact - and at least closer
to what i was looking for.

thanks again, great newsgroup.

---- dz




Bruno said:
David said:
i have a dict with a particular key - the values for this key will be
None, one valid scalar, or a list:

{mykey, None}
{mykey, "foo"}
{mykey, ["bar", "baz"]}

let's ignore the None case - in the case of the one or many values, i
want to suck the values into a list. here's one way to do this:

if mydict.has_key(mykey):
vals=[]
_v = mydict[mykey]
if isinstance(_v, types.ListType):
vals.extend(_v)
else:
vals.append(_v)
# now we can safely iterate through acts
for val in vals:
.....


my way is ugly. what's a better way?

If you have control over the dict's creation and 'filling', you may want
to handle the case there - eventually using a custom dict-like object
that stores everything (but None) in lists. The implementation code for
this object will not be less ugly than the one above, but at least
ugliness will be hidden away !-)

Else, you can shorten the code a bit (NB : ignoring the 'None' case...):

v = d[k]
v = ([v], v)[isinstance(v, list)]

And this can be hidden away in a function:

def get_as_list(d, k):
v = d[k]
return ([v], v)[isinstance(v, list)]

vals = get_as_list(mydict, mykey)


I don't like using isinstance() tests too much, but it depends on the
context...

HTH
 
B

Bruno Desthuilliers

David said:
thanks for the many responses.

i have zero control over the dict. in practice, i'm using turbogears
which is "automatically" populating the result dict with zero-to-many
choices from a generated list of HTML checkboxes. the user can select
none, one, or many, and submit. cherrypy packs the **kwargs arg full of
the selection, as i described in my op.

Are you sure you get mydict[mykey]==None if the user doesn't check any
of the checkboxes ? According to html specs, the form's dataset
shouldn't have the key at all in this case.
using a try/exception case to switch between append and extend will not
work.
Nope.

the scalar, coming back as a string, can certainly be iterated
and i'll end up with a bunch of characters in my list.
Yes.

i like what's posted below

Thanks - and BTW, please, don't top-post...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top