简体   繁体   中英

How to go about separating data in a .csv file?

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?

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']

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')]

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(',')))

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.

As I see in example line will be line = line.split(",") enoght. Maybe I didn't get something?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM