views:

81

answers:

3

I have a comma seperated file, a row looks like:

"ABC234234", 23

I want to load this into a dictionary, with the key being the first part i.e. "ABC234234"

I have to remote the double quotes also.

What's the pythonic way of doing this?

+4  A: 
import csv
d = dict(csv.reader(open("foo.txt", "rb")))
carl
Always open files for use with `csv.reader` with `mode='rb'` (Python 2.x) or `newline=''` (Python 3.x)
John Machin
I used to do this with a `for` loop. Never knew dict could do this. (But then again I only started learning Python 2 months ago :P )
vlad003
This answer would be better if you closed the file explicitly. To match the power of `with` you should use a `try/finally` to ensure the file is closed even if there is an exception from `csv.reader` for example
gnibbler
+6  A: 

I would suggest (like always) opening the CSV file with the with statement (which ensures it will be closed when you're done!) -- apart from that, @carl's answer is generally fine:

import csv

with open('yourfile.csv', 'rb') as f:
    thedict = dict(csv.reader(f))

and then freely use thedict as you require.

Note that the values (as well, of course, as the keys) will be strings. If you know that the second column always has an integer, and want to have ints as values, you could replace the assignment with

    thedict = dict((k, int(v)) for k, v in csv.reader(f))

or, if you prefer to avoid excessive compactness/density in your code, decompose this latest statement into, for example:

    ks_vs = ((k, int(v)) for k, v in csv.reader(f))
    thedict = dict(ks_vs)

or break it down even further, if you wish, of course.

This works in Python 2.6 or better. If you're stuck with 2.5, to make it work, add

from __future__ import with_statement

at the top of the module -- the rest of my advice still applies;-).

Alex Martelli
+1 the more people using `with` the better!
gnibbler
I have to strip the double quotes also. Oh and the file I am getting is actually downloaded using urllib2 from the web, so its not on disk.
Blankman
@Blankman, (1): part of cvs's work is removing quotes from around fields that are in quotes -- have you _tried_ it before complaining?-) (2): The result of `urllib2.urlopen` is a file-like object and it's perfectly suitable to pass as argument to `csv.reader`, just like the result of `open` (an actual file object) is.
Alex Martelli
+3  A: 

You asked for Pythonic. If you wish to follow one of the precepts in the Zen of Python ("Errors should never pass silently") and you want to check that there are no duplicate keys in your data, or do other error checking or sanitising (examples: key can't be an empty string, want to strip leading/trailing whitespace), you'll need to write more detailed code.

#untested example
import csv
with open('the_file.csv', 'rb') as f:
    reader = csv.reader(f)
    the_dict = {}
    for rownum, row in enumerate(reader, start=1):
        if len(row) != 2:
            error('row length is not 2', rownum, row)
            continue
        k, v = [item.strip() for item in row]
        if not k:
            error('key is empty string', ...); continue
        if k in the_dict:
            error(...); continue
        the_dict[k] = v
John Machin
much more straight forward, with the ability to modify as I insert into the dic (more readable rather).
Blankman