0

Blockquote

Help me to read my csv file. I have a csv file test8.csv and I want to read data from that file and put to dict, From the csv file : 1st row is matrices size of value dict that i will create, 2nd row is key of dict and the next is matrix of value of key :

File csv:

1,5 
OFFENSE INVOLVING CHILDREN 
95   
96
35
80
100
2,2
BATTERY,THEFT
173,209   
173,224

Output expectation:

dict={['OFFENSE INVOLVING CHILDREN']: 
      [(95,), (96,), (35,), (80,), (100,)], 
      ['BATTERY', 'THEFT']:[(173, 209), (173, 224)]}

This is my piece of code, and I don't have idea to continue:

_dir = r'D:\s2\semester 3\tesis\phyton\hasil'
with open(os.path.join(_dir, 'test8.csv'), 'rb') as csv_file:
dataReader= csv.reader(csv_file, delimiter=' ', quotechar='|')
1
  • 3
    You can not have a list as a dictionary key or I'm missing something here. Commented Jan 16, 2016 at 3:16

2 Answers 2

4

That isn't a csv file and the csv module can't help you. In a csv file, each line has an equal number of columnar fields separated by a known character such as a comma. you will need to write your own parser for this data.

This script will build up the dictionary (except it uses a tuple for the key because a list won't work...)

# todo: write a testfile so the example works
open("testfile.txt", "w"). write("""1,5 # matriks size
OFFENSE INVOLVING CHILDREN # key for dictionary
95  # list of value 
96
35
80
100
2,2
BATTERY,THEFT
173,209   # list of tuple value
173,224""")

def strip_comment(line):
    return line.split('#', 1)[0].rstrip()

mydict = {}

with open("testfile.txt") as testfile:
    for line in testfile:
        # first line is the next record "matrix size"
        columns, rows = (int(x) for x in strip_comment(line).split(','))
        # next line is the header for this record
        key = tuple(strip_comment(next(testfile)).split(','))
        # the next lines are the rows for this record
        vals = [tuple(int(x) for x in   strip_comment(next(testfile)).split(','))
            for _ in range(rows)]
        mydict[key] = vals

print(mydict)
Sign up to request clarification or add additional context in comments.

4 Comments

Acctualy this case is inverse from my question before
Sorry... comment is not part of csv file. I write it just for give explanation of my csv example. by the way, using your way... how to read data from file. what is type of testfile ? and what is type of input for testfile. In my case I just have csv file. :)
StringIO is just an object that looks like a file without actually writing a file. I updated the example to remove StringIO but to write the test file and read it from disk.
Thank you :) I will use you solution
0

CSV file is the abbreviation for comma-separated values file. Just treat what you have now as a text file.

You can first read the file into memory:

with open('test8.csv','r') as f:
    lines = f.readlines()

Then, since the structure of the file is known, the lines can be dealt with one by one.

def remove_line_comment(line,comment_char='#'):
    i = 0
    for c in line:
        if c != comment_char:
            i+=1
        else:
            break
    return line[:i]

output = dict() 

for line_number,line in enumerate(lines):
    line = remove_line_comment(line)
    line = line.strip()    # remove empty space on both sides
    line = line.split(',') # split the line with comma as the separator 

    # as indicated, I assume the first line in the file is always 
    # the indicative of the size of key and the size of value of the first diction item 
    if line_number == 0: 
        key_size, value_size = int(line[0]), int(line[1]) 
        line_number_counter = line_number 

    elif line_number == line_number_counter+1:
        # dictionary key cannot be unhashable object 
        key = line[0] if key_size == 1 else tuple(line) 
        value = []

    elif line_number >= line_number_counter+2 and line_number < line_number_counter+1+value_size: 
        value.extend[line]

    elif line_number == line_number_counter+1+value_size:
        value.extend(line)
        output[key] = value

    else:
        key_size, value_size = int(line[0]), int(line[1]) 
        line_number_counter = line_number 

This will do the trick.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.