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

dictionary of list from a file

P: n/a
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]
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

Oct 4 '06 #1
Share this Question
Share on Google+
13 Replies


P: n/a
On 4 Oct 2006 06:09:21 -0700, an**************@gmail.com
<an**************@gmail.comwrote:
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]
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.

--
I like python!
UliPad <<The Python Editor>>: http://wiki.woodpecker.org.cn/moin/UliPad
My Blog: http://www.donews.net/limodou
Oct 4 '06 #2

P: n/a
an**************@gmail.com wrote:
<snip perl example code>
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]
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.

Oct 4 '06 #3

P: n/a
On Wed, 04 Oct 2006 06:09:21 -0700, an**************@gmail.com let this
slip:
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[i]
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().
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
--
Thomas Jollans alias free-zombie
Oct 4 '06 #4

P: n/a
an**************@gmail.com wrote:
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.
--
Giovanni Bajo
Oct 4 '06 #5

P: n/a
<an**************@gmail.comwrote in message
news:11**********************@m7g2000cwm.googlegro ups.com...
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]
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
Oct 4 '06 #6

P: n/a
limodou wrote:
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)

Oct 4 '06 #7

P: n/a
Thus spoke Paul McGuire (on 2006-10-04 17:34):
<an**************@gmail.comwrote in message
>this is my first post. my "programming" background is perlish
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 ;-)
Oct 4 '06 #8

P: n/a
On 4 Oct 2006 13:11:15 -0700, sj*******@yahoo.com <sj*******@yahoo.comwrote:
limodou wrote:
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.

--
I like python!
UliPad <<The Python Editor>>: http://wiki.woodpecker.org.cn/moin/UliPad
My Blog: http://www.donews.net/limodou
Oct 5 '06 #9

P: n/a
sj*******@yahoo.com wrote:
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
Oct 5 '06 #10

P: n/a
limodou wrote:
On 4 Oct 2006 13:11:15 -0700, sj*******@yahoo.com <sj*******@yahoo.comwrote:
limodou wrote:
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.

Oct 5 '06 #11

P: n/a
sj*******@yahoo.com wrote:
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
Oct 5 '06 #12

P: n/a
Peter Otten wrote:
sj*******@yahoo.com wrote:
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".split()
['', '1']

Oct 5 '06 #13

P: n/a
On 4 Oct 2006 06:09:21 -0700, an**************@gmail.com
<an**************@gmail.comwrote:
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).
Oct 6 '06 #14

This discussion thread is closed

Replies have been disabled for this discussion.