nicholsonjf
nicholsonjf

Reputation: 1001

How can I parse this list of comma separated values

I have a list of comma-separated users and their permissions, where some users have up to 8 permissions:

user_a, permission_1
user_b, permission_1, permission_2
user_c, permission_1, permission_2, permission_3

I need my output to be a list of comma-separated users and permissions, where every user and permission pair are on a separate line:

user_a, permission_1
user_b, permission_1
user_b, permission_2
user_c, permission_1
user_c, permission_2
user_c, permission_3

My python code below using the csv module is currently not working:

import csv

with open('user_list.csv') as user_list:
    dict_reader = csv.DictReader(user_list)
    ul = []
    for row in dict_reader:
        ul.append(row)

with open('output.txt','w') as output:
    fields = 'USER','PERM1','PERM2','PERM3','PERM4',
    'PERM5','PERM6','PERM7','PERM8'
    dict_writer = csv.DictWriter(output, fields)
    csv.DictWriter.writeheader(dict_writer)
    for i in ul:
        dict_writer.writerow(i)

It's giving me the following Traceback:

Traceback (most recent call last):
  File "cops_ul_parse.py", line 15, in <module>
    dict_writer.writerow(i)
  File "C:\Python27\lib\csv.py", line 148, in writerow
    return self.writer.writerow(self._dict_to_list(rowdict))
  File "C:\Python27\lib\csv.py", line 144, in _dict_to_list
    ", ".join(wrong_fields))
ValueError: dict contains fields not in fieldnames: PERM8, PERM7, PERM6, PERM5

Any idea why this isn't working? Or, is there a better way to accomplish my desired output? Maybe a regex would work better?

Upvotes: 1

Views: 171

Answers (2)

Gareth Latty
Gareth Latty

Reputation: 89017

The issue is this line:

fields = 'USER','PERM1','PERM2','PERM3','PERM4',
'PERM5','PERM6','PERM7','PERM8'

Your code is doing fields = 'USER','PERM1','PERM2','PERM3','PERM4', (remember tuples and lists can have trailing commas after the last item), and then making another tuple ('PERM5','PERM6','PERM7','PERM8') and doing nothing with it.

Then, when you make the csv.DictWriter, it only has the fields from the first tuple - hence the error you are getting.

The solution is simple: use brackets around your tuple, which then gives you implied line continuation:

fields = ('USER','PERM1','PERM2','PERM3','PERM4',
          'PERM5','PERM6','PERM7','PERM8')

You can use a backslash to escape the line break too, but brackets are much nicer to read.

Upvotes: 1

inspectorG4dget
inspectorG4dget

Reputation: 113965

for perm in listOfPermissions:
    user, perms = perm.split(',', 1)
    for p in perms:
        print "%s, %s" %(user, p)

To write this to a file:

with open('path/to/file', 'w') as outfile:
    for perm in listOfPermissions:
        user, perms = perm.split(',', 1)
        for p in perms:
            outfile.write("%s, %s\n" %(user, p))

Upvotes: 0

Related Questions