patternpythonMinor
Managing a CSV of users and permissions
Viewed 0 times
permissionsmanagingcsvandusers
Problem
I've got a CSV that contains users and permissions in the below format, where users can have as little as one or as many as eight different permissions:
This is the desired format, with each unique user and permission pair on a new line:
My script below accomplishes this, but it's ugly, repetitive and I know there's a more Pythonic way to do it. Even worse, I had to bring the output file into Excel afterwards to filter and delete the rows with blank PERM values. Any recommendations to shorten this code and cut down on repetition would be much appreciated.
USER,PERM1,PERM2,PERM3,PERM4,PERM5,PERM6,PERM7,PERM8
jdoe,perm1,perm2
tsmith,perm1,perm2,perm3,perm4,perm5,perm6,perm7,perm8
This is the desired format, with each unique user and permission pair on a new line:
USER,PERM
jdoe,perm1
jdoe,perm2
tsmith,perm1
tsmith,perm2
tsmith,perm3
tsmith,perm4
tsmith,perm5
tsmith,perm6
tsmith,perm7
tsmith,perm8
My script below accomplishes this, but it's ugly, repetitive and I know there's a more Pythonic way to do it. Even worse, I had to bring the output file into Excel afterwards to filter and delete the rows with blank PERM values. Any recommendations to shorten this code and cut down on repetition would be much appreciated.
import csv
def reformat_ul(original_ul, formated_ul):
with open(original_ul) as user_list:
dict_reader = csv.DictReader(user_list)
ul = []
for row in dict_reader:
ul.append(row)
with open(formated_ul, 'w') as output2:
output2.write('USER,PERM\n')
for uperm in ul:
p1 = '{},{}\n'.format(uperm['USER'], uperm['PERM1'])
p2 = '{},{}\n'.format(uperm['USER'], uperm['PERM2'])
p3 = '{},{}\n'.format(uperm['USER'], uperm['PERM3'])
p4 = '{},{}\n'.format(uperm['USER'], uperm['PERM4'])
p5 = '{},{}\n'.format(uperm['USER'], uperm['PERM5'])
p6 = '{},{}\n'.format(uperm['USER'], uperm['PERM6'])
p7 = '{},{}\n'.format(uperm['USER'], uperm['PERM7'])
p8 = '{},{}\n'.format(uperm['USER'], uperm['PERM8'])
output2.write(p1)
output2.write(p2)
output2.write(p3)
output2.write(p4)
output2.write(p5)
output2.write(p6)
output2.write(p7)
output2.write(p8)
reformat_ul('user_list.csv', 'output.txt')Solution
This is shorter:
The highlights:
import csv
def reformat_ul(original_ul, formated_ul):
with open(formated_ul, 'w') as output2:
output2.write('USER,PERM\n')
with open(original_ul) as user_list:
dict_reader = csv.DictReader(user_list)
for row in dict_reader:
user = row['USER']
for key in sorted(row)[:-1]:
if row[key]:
output2.write("%s,%s\n" % (user, row[key]))
reformat_ul('user_list.csv', 'output.txt')The highlights:
- It doesn't waste memory by storing the rows in a temporary list. Using the two nested
withthere, it outputs while reading the output, piping properly
- In
sorted(row)[:-1]I take advantage of the fact that I know the column names, and thatUSERwill come after all thePERM1..PERM8. If you need a more flexible implementation then you can amend the deepestifthere, for exampleif key.startswith('PERM') and row[key]
Code Snippets
import csv
def reformat_ul(original_ul, formated_ul):
with open(formated_ul, 'w') as output2:
output2.write('USER,PERM\n')
with open(original_ul) as user_list:
dict_reader = csv.DictReader(user_list)
for row in dict_reader:
user = row['USER']
for key in sorted(row)[:-1]:
if row[key]:
output2.write("%s,%s\n" % (user, row[key]))
reformat_ul('user_list.csv', 'output.txt')Context
StackExchange Code Review Q#30473, answer score: 2
Revisions (0)
No revisions yet.