By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
464,428 Members | 1,069 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 464,428 IT Pros & Developers. It's quick & easy.

Naming dictionaries recursively

P: n/a
TYR
I'd like to do something like this; iterate through a file which
consists of data stored in dictionary format, one dict on each line,
and read each line into a new dict using one of the values in the dict
as its name...

for example:

stuff = open('data.txt')
for eachLine in stuff:
name{}
name = eachLine
.....and then do something clever to extract the value of the key
(name) from the line and use it as the dictionary's name.

A line from data.txt would look like this: {'name' : Bob, 'species' :
Humboldt, 'colour' : red, 'habits' : predatory}. Aim is to call one of
them by name, and merge the values in that dictionary into a string
pulled from another source.

Aug 17 '07 #1
Share this Question
Share on Google+
7 Replies

P: n/a
On Aug 17, 7:38 am, TYR <a.harrow...@gmail.comwrote:
I'd like to do something like this; iterate through a file which
consists of data stored in dictionary format, one dict on each line,
and read each line into a new dict using one of the values in the dict
as its name...

for example:

stuff = open('data.txt')
for eachLine in stuff:
name{}
name = eachLine
....and then do something clever to extract the value of the key
(name) from the line and use it as the dictionary's name.

A line from data.txt would look like this: {'name' : Bob, 'species' :
Humboldt, 'colour' : red, 'habits' : predatory}. Aim is to call one of
them by name, and merge the values in that dictionary into a string
pulled from another source.
I'm not sure I follow exactly what you want to do, but you can always
use eval for each line in that file.

But, if the line you provided for testing is one that actually comes
from the file, you'll have to patch it before you eval the line. I
think this regexp will work. Be careful though, it assumes that all
values are whole words, that is they don't have spaces in them.

# This is far from ideal, but you get what you pay for :).
re.sub(r':\s*(\w+)(,|})', r"': '\1'\2", line)

Anyway, after you've cleaned up your input line this ought to work:
d = eval(line)

Also, if you're building the input file from within a python program,
maybe you should consider the pickle module.

That ought to give you a good start...

jw

Aug 17 '07 #2

P: n/a
On Fri, 17 Aug 2007 12:38:16 +0000, TYR wrote:
I'd like to do something like this; iterate through a file which
consists of data stored in dictionary format, one dict on each line,
and read each line into a new dict using one of the values in the dict
as its name...
Store the dictionaries in a dictionary with that value as key.
A line from data.txt would look like this: {'name' : Bob, 'species' :
Humboldt, 'colour' : red, 'habits' : predatory}. Aim is to call one of
them by name, and merge the values in that dictionary into a string
pulled from another source.
So the tougher problem seems to be parsing those lines. That is not a
valid Python dictionary unless the names `Bob`, `Humboldt`, `red`, and
`predatory` are not already defined. So you can't just ``eval`` it.

Ciao,
Marc 'BlackJack' Rintsch
Aug 17 '07 #3

P: n/a
TYR
So the tougher problem seems to be parsing those lines. That is not a
valid Python dictionary unless the names `Bob`, `Humboldt`, `red`, and
`predatory` are not already defined. So you can't just ``eval`` it.
In what way? {'key': val}, right?

Anyway, I can always change the format they go into the file in.


Aug 17 '07 #4

P: n/a
On Aug 17, 7:38 am, TYR <a.harrow...@gmail.comwrote:
I'd like to do something like this; iterate through a file which
consists of data stored in dictionary format, one dict on each line,
and read each line into a new dict using one of the values in the dict
as its name...

for example:

stuff = open('data.txt')
for eachLine in stuff:
name{}
name = eachLine
....and then do something clever to extract the value of the key
(name) from the line and use it as the dictionary's name.

A line from data.txt would look like this: {'name' : Bob, 'species' :
Humboldt, 'colour' : red, 'habits' : predatory}. Aim is to call one of
them by name, and merge the values in that dictionary into a string
pulled from another source.
Pyparsing includes an example that is very similar to this. Here is
that example adapted to your specific data:

from pyparsing import *

line = """{'name' : Bob, 'species' : Humboldt, 'colour' : red,
'habits' : predatory}"""

LBRACE,RBRACE,COLON,COMMA = map(Suppress,"{}:,")
key = sglQuotedString.setParseAction(removeQuotes)
value = OneOrMore(Word(alphanums))\
.setParseAction(keepOriginalText)
entry = Group(key + COLON + empty + value)
lineExpr = LBRACE + Dict(delimitedList(entry)) + RBRACE

parsedData = lineExpr.parseString(line)

# some examples of accessing the parsed data
print "Keys:", parsedData.keys()
print parsedData.name
print parsedData.colour
print "Name: %(name)s \nSpecies: %(species)s \n" \
"Colour: %(colour)s \nHabits: %(habits)s" % parsedData

Prints:

Keys: ['colour', 'habits', 'name', 'species']
Bob
red
Name: Bob
Species: Humboldt
Colour: red
Habits: predatory

-- Paul

Aug 17 '07 #5

P: n/a
On Aug 17, 3:43 pm, TYR <a.harrow...@gmail.comwrote:
So the tougher problem seems to be parsing those lines. That is not a
valid Python dictionary unless the names `Bob`, `Humboldt`, `red`, and
`predatory` are not already defined. So you can't just ``eval`` it.

In what way? {'key': val}, right?

Anyway, I can always change the format they go into the file in.
If you control the file format then you could create a valid python
list of dictionaries as the intermediate file format. Something like:

data = [
{'name' : 'Bob', 'species' : 'Humboldt', 'colour' : 'red',
'habits' : 'predatory'},
{ ... },
...
}

You can then name the file with a .py ending and import it as a list
of dictionaries that you can then process to form a dict of dicts:

datadict = dict( (data2name(d), d) for d in modulename.data )

- Paddy.

Aug 17 '07 #6

P: n/a
TYR
That sounds like a solution. I think the core of the question is as
follows; if I was to call the dict() function for each line, thus
creating a dictionary, and then rename it to dict['name'], will there
be a namespace collision on the next loop when dict() is called again?
Obviously the first dictionary will still be there, as it still has a
refcount of 1; but if it gets overwritten, will the object that the
new name refers to be overwritten too?

Aug 18 '07 #7

P: n/a
On Aug 18, 11:44 am, TYR <a.harrow...@gmail.comwrote:
That sounds like a solution. I think the core of the question is as
follows; if I was to call the dict() function for each line, thus
creating a dictionary, and then rename it to dict['name'], will there
be a namespace collision on the next loop when dict() is called again?
Obviously the first dictionary will still be there, as it still has a
refcount of 1; but if it gets overwritten, will the object that the
new name refers to be overwritten too?
if data2name might give colliding names then you could use tuples as
dictionary keys as shown below:

import modulename
datadict = dict( ((data2name(d), count), d)
for count,d in enumerate(modulename.data) )

Generally, if you try and create two keys with the same name in a
dictionary, they will clash and only the second value is retained.

- Paddy.

Aug 18 '07 #8

This discussion thread is closed

Replies have been disabled for this discussion.