a clean way to define dictionary

Alex Martelli aleax at aleax.it
Wed Jun 18 04:40:11 EDT 2003


Kendear wrote:

> 
> i hope to define a dictionary this way:
> 
> lst = """
> a    1
> foo  3
> bar  234
> joe  321
> """
> 
> lst = lst.split()
> 
> now lst refers to  ['a', '1', 'foo', '3', 'bar', '234', 'joe', '321']

If you could rely on the newlines, 

  lst = [ x.split() for x in lst.split('\n') if not x.isspace() ]

would give you [['a', '1'], ['foo', '3'], ['bar', '234'], ['joe', '321']] ,
meaning that dict(lst) would immediately return the dictionary you want
(except that the values still need to be run through 'eval', which you
could do separately).  Just pointing out that you may have flattened lst
too much with that single split call, so you later need to recover some
structure (originally indicated by the newlines) that you have just
thrown away -- you might choose to NOT throw it away in the first place.

Also, as already mentioned elsewhere on the thread, avoid using dict as
your own variable name, since that stops you from calling Python's own
built-in 'dict' and severely restricts your options!  So I'll call the
name of the dictionary you're building 'adict' in the following.  With
lst made into a list of lists (split by \n first, and only line by line
split on generic whitespace), the loop equivalent to your following:

> i want to do something like
> 
> dict = {}
> for key, value in lst:
>      dict[key] = eval(value)

would indeed work just perfectly -- the reason it doesn't work after the
single call to lst.split is that you've flattened away the structure.

Still, if you're given an already-flattened list by an evil godmother,
bunching it up again isn't beyond human ingenuity (just some amount of
wasted effort if you could have avoided the original flattening;-).
[ [lst[i],list[i+1]] for i in range(0,len(lst),2) ] would be a typical,
simple list comprehension to do this bunching-up, for example -- so you
could loop

for key, value in [ [lst[i],list[i+1]] for i in range(0,len(lst),2) ]:

or, as others have indicated, in Python 2.3 you could slice lst[::2]
and lst[1::2] to get the even and odd items and zip them up again:

for key, value in zip(lst[::2], lst[1::2]):

but that doesn't work in 2.2 (you need 2.3 for that) -- same for
itertools.islice which might be used to construct similar functionality.


> or is there a more common way to define a dictionary
> without all the punctuation marks?

What 'punctuation marks' are you referring to?  Those in the normal
literal form of dictionaries?  Those are just braces around the lot,
colons to separate key and value, commas to separate the items, i.e.
    {1:2, 3:4}
but apparently in your case some of the values are meant to be ints
and others are meant to be strings, so that would require some more
punctuation quite independently from the fact that those values are
then meant to become keys and values in a dictionary.  If you have
metaknowledge such as "all keys are strings, all values ints" then
you need to encode that somehow -- might as well be in your code that
builds the dictionary.


Alex





More information about the Python-list mailing list