dictionary of list from a file

  • Thread starter andrea.spitaleri
  • Start date
A

andrea.spitaleri

Hi guys,
this is my first post. my "programming" background is perlish scripting
and now I am learning python. I need to create a dictionary of list
from a file. Normally in perl I use to do like:

while(<IN>){
@info=split(/ +/,$_);
push (@{$tmp{$info[0]}},$info[1]);
}

and then
foreach $key (keys %tmp){
print "$key -> @{$tmp{$key}}\n";
}
i get

2 -> 1 2 3 4
7 -> 7 8 9 10

in python I tried:
b={}
a=[]
for line in fl.readlines():
info=lines.split()
b[info[0]] = a.append(info[1])

and then
for i in b:
print i,b
i get
2 None
7 None

data file is:
2 1
2 2
2 3
2 4
7 7
7 8
7 9
7 10

Any help??
Thanks in advance
Best Regards

Andrea
 
L

limodou

Hi guys,
this is my first post. my "programming" background is perlish scripting
and now I am learning python. I need to create a dictionary of list
from a file. Normally in perl I use to do like:

while(<IN>){
@info=split(/ +/,$_);
push (@{$tmp{$info[0]}},$info[1]);
}

and then
foreach $key (keys %tmp){
print "$key -> @{$tmp{$key}}\n";
}
i get

2 -> 1 2 3 4
7 -> 7 8 9 10

in python I tried:
b={}
a=[]
for line in fl.readlines():
info=lines.split()
b[info[0]] = a.append(info[1])

and then
for i in b:
print i,b
i get
2 None
7 None

data file is:
2 1
2 2
2 3
2 4
7 7
7 8
7 9
7 10

Any help??
Thanks in advance
Best Regards

Andrea

here is my program

d = {}
for line in file('test.txt'):
line = line.strip()
if line:
k, v = line.strip().split()
d.setdefault(k, []).append(v)
print d

Dict in Python has a setdefault method, if there is a key in dict,
it'll return the value, and if there is not a key existed, it'll
insert a key with the value supplied by the second parameter and
return the value. So using setdefault will be very handy for inserting
key.
 
K

keirr

in python I tried:
b={}
a=[]
for line in fl.readlines():
info=lines.split()
b[info[0]] = a.append(info[1])

and then
for i in b:
print i,b
i get
2 None
7 None

data file is:
2 1
2 2
2 3
2 4
7 7
7 8
7 9
7 10

Any help??

Andrea,
first the append method returns None, as you have discovered; it makes
an inplace update (to a in your example) but does not return the list
it has updated. This has surprised a few people in the past :)
Here is what I've used before for updating lists values in a
dictionary.

d[key] = d.get(key, []) + [value]

where d is a dict(ionary)

Hope this helps.

Keir.
 
T

Thomas Jollans

b={}
a=[]
for line in fl.readlines():
info=lines.split()
b[info[0]] = a.append(info[1])
append does not return a value. you'll want something like
d = {}
for line in fl:
key, value = line.strip().split()
if key not in d: d[key] = []
d[key].append(value)

or something with setdefault, as limodou suggested.
for i in b:
print i,b

you can also use:
for k,v in d.iteritems():
print k,v

if you're dealing with integers only, you'll want to convert the data when
reading using int() and long().
 
G

Giovanni Bajo

while(<IN>){
@info=split(/ +/,$_);
push (@{$tmp{$info[0]}},$info[1]);
}

and then
foreach $key (keys %tmp){
print "$key -> @{$tmp{$key}}\n";
}

Python 2.5 introduced a dictionary type with automatic creation of values,
ala Perl:

===============================
from collections import defaultdict

d = defaultdict(list)
for line in fl:
k, v = line.strip().split()
d[k].append(v)

for k,v in d.items():
print k, v
===============================

Notice that Python is always more strongly typed, so you have to specify a
factory function.
 
P

Paul McGuire

Hi guys,
this is my first post. my "programming" background is perlish scripting
and now I am learning python. I need to create a dictionary of list
from a file. Normally in perl I use to do like:

while(<IN>){
@info=split(/ +/,$_);
push (@{$tmp{$info[0]}},$info[1]);
}

and then
foreach $key (keys %tmp){
print "$key -> @{$tmp{$key}}\n";
}
i get

2 -> 1 2 3 4
7 -> 7 8 9 10

in python I tried:
b={}
a=[]
for line in fl.readlines():
info=lines.split()
b[info[0]] = a.append(info[1])

and then
for i in b:
print i,b
i get
2 None
7 None

data file is:
2 1
2 2
2 3
2 4
7 7
7 8
7 9
7 10

Any help??
Thanks in advance
Best Regards

Andrea


I'll see your perlish line noise, and raise you this obfuscapython: :)

data = """\
2 1 2 3 4
7 7 8 9 10
5 1 3 5 7 9
2 6 8 10""".split('\n') # similar to file.readlines(), but easier to paste
into news post
import operator, itertools
item = operator.itemgetter
b = dict( (k,sum(map(lambda g:g[1:],grps),[]))
for (k,grps) in itertools.groupby( sorted(
map(str.split,data) ), item(0) ) )
for item in sorted(b.items()):
print "%s -> %s" % item

prints:
2 -> ['1', '2', '3', '4', '6', '8', '10']
5 -> ['1', '3', '5', '7', '9']
7 -> ['7', '8', '9', '10']

-- Paul
 
S

sjdevnull

limodou said:
here is my program

d = {}
for line in file('test.txt'):
line = line.strip()
if line:
k, v = line.strip().split()
d.setdefault(k, []).append(v)
print d

Minor nits: you call strip twice, when you don't need to. just omit
the second call.
Also, I'm not sure stripping the line is the right thing per the spec;

d = {}
for line in [l[:-1] for l in file('test.txt', 'rU') if len(l)>1]:
k,v = line.split()
d.setdefault(k,[]).append(v)
 
M

Mirco Wahab

Thus spoke Paul McGuire (on 2006-10-04 17:34):
I'll see your perlish line noise, and raise you this obfuscapython: :)

data = """\
2 1 2 3 4
7 7 8 9 10
5 1 3 5 7 9
2 6 8 10""".split('\n') # similar to file.readlines(), but easier to paste
into news post
import operator, itertools
item = operator.itemgetter
b = dict( (k,sum(map(lambda g:g[1:],grps),[]))
for (k,grps) in itertools.groupby( sorted(
map(str.split,data) ), item(0) ) )
for item in sorted(b.items()):
print "%s -> %s" % item

prints:
2 -> ['1', '2', '3', '4', '6', '8', '10']
5 -> ['1', '3', '5', '7', '9']
7 -> ['7', '8', '9', '10']

Hehe! not bad, lets do the reverse in Perl then too ;-)

This should be *one line*, operating on a dictionary %h:

s/(\d+)\s+(\d+.+)$/push @{$h{$1}},split' ',$2/eg for @data;

(is at least as obfuscated as yours) - add another line for the output:

print( "$_ => @{$h{$_}} \n") for sort keys %h;

will print (as yours):

2 => 1 2 3 4 6 8 10
5 => 1 3 5 7 9
7 => 7 8 9 10

if your data:

@data = split"\n",
'2 1 2 3 4
7 7 8 9 10'
5 1 3 5 7 9
2 6 8 10';

.... is fed in. What does all this tell us?
==> Obfuscated Python is *much longer* than
its Perl counterpart ;-)

Regards

Mirco

PS.: I tried to pull the dict in Python
out of a regex search too - but failed.
I'll try tomorrow again ;-)
 
L

limodou

limodou said:
here is my program

d = {}
for line in file('test.txt'):
line = line.strip()
if line:
k, v = line.strip().split()
d.setdefault(k, []).append(v)
print d

Minor nits: you call strip twice, when you don't need to. just omit
the second call.

Yes, I forgot that.
Also, I'm not sure stripping the line is the right thing per the spec;

d = {}
for line in [l[:-1] for l in file('test.txt', 'rU') if len(l)>1]:
k,v = line.split()
d.setdefault(k,[]).append(v)
[l[:-1] for l in file('test.txt', 'rU') if len(l)>1]

this line I think will create a list, and if the file is large, it'll
consume many memory I think.

And I think using strip is more clear than list comprehension, except
for the memory consume.
 
P

Peter Otten

d = {}
for line in [l[:-1] for l in file('test.txt', 'rU') if len(l)>1]:
k,v = line.split()
d.setdefault(k,[]).append(v)

Try that with a test.txt where the last line has no newline.

Peter
 
S

sjdevnull

limodou said:
limodou said:
here is my program

d = {}
for line in file('test.txt'):
line = line.strip()
if line:
k, v = line.strip().split()
d.setdefault(k, []).append(v)
print d

Minor nits: you call strip twice, when you don't need to. just omit
the second call.

Yes, I forgot that.
Also, I'm not sure stripping the line is the right thing per the spec;

d = {}
for line in [l[:-1] for l in file('test.txt', 'rU') if len(l)>1]:
k,v = line.split()
d.setdefault(k,[]).append(v)
[l[:-1] for l in file('test.txt', 'rU') if len(l)>1]

this line I think will create a list, and if the file is large, it'll
consume many memory I think.

And I think using strip is more clear than list comprehension, except
for the memory consume.

Good point on memory.

You can use strip in a list (or generator) comprehension just fine.

For example (using a generator to avoid memory consumption):

for line in (l.rstrip("\n") for l in file("test.txt", "rU") if l[0] !=
"\n"):
k, v = line.split()
d.setdefault(k, []).append(v)

It's a matter of taste, but I think this isolates the bean-counting
"get rid of newlines/blank lines" stuff from the real processing and
makes it a bit clearer what real work you're doing with each line.
 
P

Peter Otten

for line in (l.rstrip("\n") for l in file("test.txt", "rU") if l[0] !=
"\n"):
   k, v = line.split()
   d.setdefault(k, []).append(v)

Note that this snippet will produce the same output with or without the
rstrip() method call.

Peter
 
S

sjdevnull

Peter said:
for line in (l.rstrip("\n") for l in file("test.txt", "rU") if l[0] !=
"\n"):
\001\001\001k,\001v\001=\001line.split()
\001\001\001d.setdefault(k,\001[]).append(v)

Note that this snippet will produce the same output with or without the
rstrip() method call.

Wow. That's not at all what I expected. I would've thought I'd see:['', '1']
 
H

hanumizzle

Hi guys,
this is my first post. my "programming" background is perlish scripting
and now I am learning python. I need to create a dictionary of list
from a file. Normally in perl I use to do like:

You may wish to consider some kind of data serialization. For python
specifically, there's pickle and cPickle, for many platforms there is
YAML (I recommend this; the py binding is really good), and as a last
resort you can use XML (yuck).
 

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,996
Messages
2,570,238
Members
46,826
Latest member
robinsontor

Latest Threads

Top