YusufUMS
YusufUMS

Reputation: 1493

Splitting elements of a list in python

I have a list contains set of the history of a file. I need to separate each element in the list into several columns and save it to CSV file. The columns I need are "commit_id, filename, committer, date, time, line_number, code". I tried to split them using space, but it didn't work for the committer and the code. Also, I need to remove the opening parentheses before committer's name and the closing parentheses after line number. Suppose, this is my list:

my_list = [
 'f5213095324 master/ActiveMasterManager.java              (Michael Stack      2010-08-31 23:51:44 +0000   1) /**',
 'f5213095324 master/ActiveMasterManager.java              (Michael Stack      2010-08-31 23:51:44 +0000   2)  *',
 'f5213095324 master/ActiveMasterManager.java              (Michael Stack      2010-08-31 23:51:44 +0000   3)  * Licensed to the Apache Software Foundation (ASF) under one',
 'f5213095324 master/ActiveMasterManager.java              (Michael Stack      2010-08-31 23:51:44 +0000   4)  * or more contributor license agreements.',
 ...
 'd6ed1130d51 master/ActiveMasterManager.java              (Michael Stack      2011-04-28 19:51:25 +0000 281) }'
 ]

desired csv output:

commit_id   | filename                         | committer     | date       | time     | line_number | code 
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
f5213095324 | master/ActiveMasterManager.java  | Michael Stack | 2010-08-31 | 23:51:44 | 1           | /**
f5213095324 | master/ActiveMasterManager.java  | Michael Stack | 2010-08-31 | 23:51:44 | 2           | *
f5213095324 | master/ActiveMasterManager.java  | Michael Stack | 2010-08-31 | 23:51:44 | 3           | * Licensed to the Apache Software Foundation (ASF) under one
f5213095324 | master/ActiveMasterManager.java  | Michael Stack | 2010-08-31 | 23:51:44 | 4           | * or more contributor license agreements.
........
d6ed1130d51 | master/ActiveMasterManager.java  | Michael Stack | 2011-04-28 | 19:51:25 | 281         | }

I tried using method str(my_list).replace(" ",'').split(" ") to make a new list before save it into csv file, but it didn't work. Any help will be appreciated. Thanks.

Upvotes: 0

Views: 77

Answers (3)

Patrick Haugh
Patrick Haugh

Reputation: 60944

Here's a regex solution

import re
import csv

my_list = [
     'f5213095324 master/ActiveMasterManager.java              (Michael Stack      2010-08-31 23:51:44 +0000   1) /**',
     'f5213095324 master/ActiveMasterManager.java              (Michael Stack      2010-08-31 23:51:44 +0000   2)  *',
     'f5213095324 master/ActiveMasterManager.java              (Michael Stack      2010-08-31 23:51:44 +0000   3)  * Licensed to the Apache Software Foundation (ASF) under one',
     'f5213095324 master/ActiveMasterManager.java              (Michael Stack      2010-08-31 23:51:44 +0000   4)  * or more contributor license agreements.',
     'd6ed1130d51 master/ActiveMasterManager.java              (Michael Stack      2011-04-28 19:51:25 +0000 281) }'
     ]


pat = re.compile(r'(?P<commit_id>\w+)\s+(?P<filename>[^\s]+)\s+\((?P<commiter>.+)\s+(?P<date>\d{4}-\d\d-\d\d)\s+(?P<time>\d\d:\d\d:\d\d).+(?P<line_number>\b\d+\b)\)\s+(?P<code>.+)')

with open('somefile.csv', 'w+', newline='') as f:
    writer = csv.writer(f)
    writer.writerow(['commit_id', 'filename', 'commiter', 'date', 'time', 'line_number', 'code'])
    for line in my_list:
        writer.writerow([field.strip() for field in pat.match(line).groups()])

You may want to play around with the csv.writer to get the prettified output you want. This ends up with

commit_id,filename,commiter,date,time,line_number,code
f5213095324,master/ActiveMasterManager.java,Michael Stack,2010-08-31,23:51:44,1,/**
f5213095324,master/ActiveMasterManager.java,Michael Stack,2010-08-31,23:51:44,2,*
f5213095324,master/ActiveMasterManager.java,Michael Stack,2010-08-31,23:51:44,3,* Licensed to the Apache Software Foundation (ASF) under one
f5213095324,master/ActiveMasterManager.java,Michael Stack,2010-08-31,23:51:44,4,* or more contributor license agreements.
d6ed1130d51,master/ActiveMasterManager.java,Michael Stack,2011-04-28,19:51:25,281,}

Upvotes: 1

JackNorthrup
JackNorthrup

Reputation: 353

Maybe a bit bit hacked up, but gives the exact format you wanted on Python2.7 It is something to work from. Results from my knowledge and a couple stack-overflow searches

my_list = [
     'f5213095324 master/ActiveMasterManager.java              (Michael Stack      2010-08-31 23:51:44 +0000   1) /**',
     'f5213095324 master/ActiveMasterManager.java              (Michael Stack      2010-08-31 23:51:44 +0000   2)  *',
     'f5213095324 master/ActiveMasterManager.java              (Michael Stack      2010-08-31 23:51:44 +0000   3)  * Licensed to the Apache Software Foundation (ASF) under one',
     'f5213095324 master/ActiveMasterManager.java              (Michael Stack      2010-08-31 23:51:44 +0000   4)  * or more contributor license agreements.',
     'd6ed1130d51 master/ActiveMasterManager.java              (Michael Stack      2011-04-28 19:51:25 +0000 281) }'
     ]
import re
import csv
from time import sleep
def SpaceToDelimit(Str, orig, new, Nright):
    li = Str.rsplit(orig, Nright)
    return new.join(li)
def nth_repl(s, sub, repl, nth):
    find = s.find(sub)
    # if find is not p1 we have found at least one match for the substring
    i = find != -1
    # loop util we find the nth or we find no match
    while find != -1 and i != nth:
        # find + 1 means we start at the last match start index + 1
        find = s.find(sub, find + 1)
        i += 1
    # if i  is equal to nth we found nth matches so replace
    if i == nth:
        return s[:find]+repl+s[find + len(sub):]
    return s
# notice my input was from your my_list above
spamreader = csv.reader(my_list, delimiter='\t', quotechar='|')
print "commit_id   | filename                        | committer     | date \      | time     | line_number | code "\
print "---------------------------------------------------------------------------"
for row in spamreader:
    row = str(row)
    row = re.sub(' +',' ',row)
    rowz = (''.join(row))
    nl= rowz[2:-3]
    nl = nl.replace(" ", " | ", 8) 
    nl = nl.replace("(","") 
    nl = nl.replace(")","")
    TEXT = nth_repl(nl, " | ", " ", 3)
    print TEXT

Results from Print:

commit_id   | filename                        | committer     | date       | time     | line_number | code 
-------------------------------------------------------------------------------------------------------------
f5213095324 | master/ActiveMasterManager.java | Michael Stack | 2010-08-31 | 23:51:44 | +0000 | 1 | /*
f5213095324 | master/ActiveMasterManager.java | Michael Stack | 2010-08-31 | 23:51:44 | +0000 | 2 | 
f5213095324 | master/ActiveMasterManager.java | Michael Stack | 2010-08-31 | 23:51:44 | +0000 | 3 | * Licensed to the Apache Software Foundation ASF under on
f5213095324 | master/ActiveMasterManager.java | Michael Stack | 2010-08-31 | 23:51:44 | +0000 | 4 | * or more contributor license agreements
d6ed1130d51 | master/ActiveMasterManager.java | Michael Stack | 2011-04-28 | 19:51:25 | +0000 | 281 | 

Upvotes: 0

Rahul
Rahul

Reputation: 11520

I think your file is tsv

Try this.

import csv
with open('eggs.csv', newline='') as csvfile:
    spamreader = csv.reader(csvfile, delimiter='\t', quotechar='|')
    for row in spamreader:
        print(' | '.join(row))

If this not helps then i think you might have to use regex as there are spaces in your value and the file is also space separated.

Upvotes: 0

Related Questions