2

I am trying to read in this text file.

A B C D
1 5 6 7
2 8 9 10
3 .......
4 .......

The letter are brought in as a line, then I just bring in all the values as floats as

with open('file.txt', 'r') as f:
  headings = f.readline()

  numbers = [float(n) for n in f.read().split()] #read values to the 'numbers' as a list 
  print numbers

So I have a long list of all the integers.

But I want the dictionary in this format:

my_dict( { 1: [5,6,7], 2:[8,9,10] } )

so the first column of files numbers are the keys, and the rest are a list correlating to their respective key.

I am setting up every 4th value as a key with a loop, but how can I easily get the rest of the values as a list into that respective key.

Mazdak
  • 105,000
  • 18
  • 159
  • 188
cc6g11
  • 477
  • 2
  • 10
  • 24

5 Answers5

5
mydict = {}
with open('file.txt', 'r') as f:
    headings = f.readline()

    for row in f:
        row = row.split()
        key = row[0]
        vals = row[1:]
        mydict[key] = vals

Something like that? Or have i missunderstood your desired result? Since you're not using the actual headers A B C D ... I'm not going to try and do something with them so i'll leave your solution for that as it is.

Also you've written some sort of class called my_dict (?) which I won't try to use because I have no idea what it actually is.

If you need the values to be integers along your output, simply do something like:

row = row.split()
row = list(int(n) for n in row)
Torxed
  • 22,866
  • 14
  • 82
  • 131
  • Works perfect. I'm new to python coming from C, can you explain WHY the for loop works the way it does? THANKS! – cc6g11 Jul 09 '15 at 08:24
  • @cc6g11 sure, i'd love to. But you mean the `for row in f`? It indirectly calls `f.readline()` as a iterator object enabling you to work line by line on the file. you could also do `for row in f.readline()` :) – Torxed Jul 09 '15 at 08:26
0

Reading can be done with numpy loadtxt or genfromtxt. To create the dictionary, I'd prefer a dictionary comprehension. Note that I have used commas as separator for my sample file.

import numpy as np

data = np.genfromtxt('filename.csv', delimiter=',', skip_header=1, dtype=np.float32)
mydict = {row[0]: row[1:] for row in data}

print mydict
>> {1.0: array([  5.,   6.,  12.], dtype=float32),
>> 2.0: array([  6.,   9.,  13.], dtype=float32),
>> 3.0: array([  7.,  10.,  14.], dtype=float32),
>> 4.0: array([  8.,  11.,  15.], dtype=float32)}

dtypes can, of course, be modified according to your requirements.

Community
  • 1
  • 1
Daniel Lenz
  • 3,334
  • 17
  • 36
0

You can do this:

i = iter(numbers) print [{r[0]: list(r[1:]) for r in zip(i,i,i,i)}]

mac
  • 9,885
  • 4
  • 36
  • 51
0

You can do it easily with the csv module and dict with a generator expression:

import csv

with open('file.txt', 'r') as f:
    next(f) # skip header
    r = csv.reader(f, delimiter=" ")
    d = dict((int(row[0]), map(int,row[1:])) for row in r)
    print(d)

{1: [5, 6, 7], 2: [8, 9, 10]}

If you have repeating keys then you will need another approach or you will lose data, a collections.defaultdict will handle repeats:

import csv
from collections import defaultdict
with open('file.txt', 'r') as f:
    next(f)
    d = defaultdict(list)
    r = csv.reader(f,delimiter=" ")
    for row in r:
       d[row[0]].extend(map(int,row[1:]))

If you want every four rows in its own dict you can use itertools.islice on the csv.reader object:

import csv
from itertools import islice
with open('file.txt', 'r') as f:
    next(f) # skip header
    r = csv.reader(f, delimiter=" ")
    out = []
    for row in iter(lambda: list(islice(r, 4)),[]):
        out.append(dict((int(r[0]), map(int,r[1:])) for r in row ))

Which for:

A B C D
1 5 6 7
2 8 9 10
5 5 6 7
6 8 9 10
1 2 3 4
2 2 2 2
3 3 3 3
4 4 4 4

Will output:

[{1: [5, 6, 7], 2: [8, 9, 10], 5: [5, 6, 7], 6: [8, 9, 10]}, {1: [2, 3, 4], 2: [2, 2, 2], 3: [3, 3, 3], 4: [4, 4, 4]}]

You can put it all inside a list comp:

 out = [dict((int(r[0]), map(int,r[1:])) for r in row) 
       for row in iter(lambda: list(islice(r, 4)),[])]
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
  • For your first method I changed the delimiter because its tabs not spaces in my file, works fine. I do have repeating keys, every four lines the key will be repeated BUT I would like them in separate dictionaries because they can just be operated with as separate instances of a calculation class. – cc6g11 Jul 09 '15 at 09:21
  • @cc6g11, then we just need to use itertools.islice. I will edit – Padraic Cunningham Jul 09 '15 at 09:21
  • @cc6g11, you want a list of dicts yes? – Padraic Cunningham Jul 09 '15 at 09:29
  • @ Padraic Cunningham So what is the correct way to reference any key or any part of its respective list? – cc6g11 Jul 09 '15 at 14:30
  • @cc6g11, `d[key]` will give you the list/value. If you want to get a certain item from the list use `d[key][index]`. What are you actually doing with the data? Also to access the list of dicts either iterate or index the list to get each dict then access as above. You can also store a list of lists for each key if you change extend to append in the defaultdict code – Padraic Cunningham Jul 09 '15 at 15:11
0

Since you need it in float and if you want to know how to do it in a dictionary comprehension

this answer is just a modification to Torexed's answer

with open('file.txt', 'r') as f:
    headings = f.readline()
    mydict={float(row[0]):[float(i) for i in row[1:]] for row in (rows.split(',') for rows in f)}
    print mydict
Ja8zyjits
  • 1,433
  • 16
  • 31