Reputation: 761
I have a .csv file that includes a long line of data. The data looks something along the lines of:
Name,Gender,Age John Smith,M,23 Ashley Jones,F,18 James Smith Johns,M,20
My end goal is to separate all of the data so I can put them into rows. My intended result would be:
['Name','Gender','Age','John Smith','M','23','Ashley Jones','F','18','James Smith Jones','M','20']
However, using something like:
line = line.split(",")
line = line.split(" ")
Will not work as it will separate them at the , or space and there will be values like:
'Age John Smith' or 'Age','John','Smith'
Is there any way to work around this?
Upvotes: 0
Views: 163
Reputation: 1882
There are nice re
-solutions, but I just wanted to add this non-regex solution:
>>> s = "John Smith,M,23 Ashley Jones,F,18 James Smith Johns,M,20"
>>> sum((item.split(None, 1) for item in s.split(',')), list())
['Name', 'Gender', 'Age', 'John Smith', 'M', '23', 'Ashley Jones', 'F', '18', 'James Smith Johns', 'M', '20']
Instead of sum
, you can also use itertools.chain
. But in the end, it does not seem to be shorter at all.
>>> list(itertools.chain(*[item.split(None, 1) for item in s.split(',')]))
or better
>>> list(itertools.chain.from_iterable(item.split(None, 1) for item in s.split(',')))
Upvotes: 1
Reputation: 44444
A regular expression way. :-)
>>> s = "John Smith,M,23 Ashley Jones,F,18 James Smith Johns,M,20" #Note: no title here.
>>> [(x.group(1), x.group(3), x.group(4)) for x in re.finditer(r"(\S+( \S+)),(\S),(\d+)",s)]
[('John Smith', 'M', '23'), ('Ashley Jones', 'F', '18'), ('Smith Johns', 'M', '20')]
Note that I have removed the title (first line), you'll need to modify the regexp accordingly, or modify the input string.
Upvotes: 0
Reputation: 713
Here's a solution using a regular expression:
re.compile("([^,]+),([^,]+),(\d+|Age)\s+").findall("Name,Gender,Age John Smith,M,23 Ashley Jones,F,18 James Smith Johns,M,20")
The result for this will be:
[('Name', 'Gender', 'Age'), ('John Smith', 'M', '23'), ('Ashley Jones', 'F', '18')]
Upvotes: 3
Reputation: 250951
Split at ,
first and then iterate over that list and split at each item at whitespaces. If after splitting at whitespaces number of items returned are more than 1 then return the first item and rest of the items separately otherwise simply return the first item.
import csv
def solve(row):
for item in row:
spl = item.split(None, 1)
if len(spl) > 1:
yield spl[0]
yield spl[1]
else:
yield spl[0]
...
with open('abc1') as f:
reader = csv.reader(f, delimiter=',')
for row in reader:
print list(solve(row))
...
['Name', 'Gender', 'Age', 'John Smith', 'M', '23', 'Ashley Jones', 'F', '18', 'James Smith Johns', 'M', '20']
Upvotes: 4
Reputation: 1416
As I see in example line will be line = line.split(",")
enoght. Maybe I didn't get something?
Upvotes: -1