用户指定的csv在Python 3中读取和打印

时间:2013-08-17 20:43:38

标签: python csv python-3.x

我有一个脚本,应该在位于同一目录的用户指定的2列csv文件中读取,对数据进行一些数学运算,并将结果打印到stdout,这是另一个用户定义的csv文件。我在2.7.5中做到了,但现在刚刚移到3.2,它不起作用。我并不感到震惊,但我在编程方面缺乏经验,而且我在如何使它在Python 3中工作时遇到了麻烦。

我已经将代码剥离了它的基本读取和打印元素以前工作但它仍然无法在3.2中工作,尽管做了一些更明显的修改,它只是卡住而且从不打印到新文件。我尝试过使用2to3.py但它会抛出一个错误的输入parseerror并且没有进行任何更改!我宁愿知道为什么它现在无论如何都不起作用。

我想要的命令类型是;

somedirectory>myscript inputdata.csv > outputdata.csv

这是Python 2.7.5脚本的精简版本,它可以让你看到我在做什么,(我已经留下了所有的导入)

import fileinput, math, sys, numpy as np
from numpy import linspace, loadtxt, ones, convolve
from optparse import OptionParser

def main():
    parser = OptionParser() 
    options,args = parser.parse_args()
    try:
        data = [(line.rstrip()).split(',') for line in fileinput.input(args)]
    except IOError as detail:
        print >> sys.stderr, detail
        sys.exit(2)

    '''kept these lines in just to make sure the data is in the same format as when it worked before'''
    t = [float(row[0]) for row in data]
    m = [float(row[1]) for row in data]
    result = [[a,b] for a,b in zip(t, m)]

    for line in result:
        print >> sys.stdout, str(line[0]) + ',' + str(line[1])

options = 0
if __name__ == "__main__":
    main()

显然Print现在是一个函数,不推荐使用Optparse可以转换为Argparse等

所以我觉得这样的事情没问题,

import fileinput, math, sys, inspect, numpy as np
from numpy import linspace, loadtxt, ones, convolve
from argparse import ArgumentParser

def main():
    parser = ArgumentParser()   
    options,args = parser.parse_args()
    try:
        data = [(line.rstrip()).split(',') for line in fileinput.input(args)]
    except IOError as detail:
        print(detail, file=sys.stderr)
        sys.exit(2)

    '''kept these lines in just to make sure the data is in the same format as when it worked before'''
    t = [float(row[0]) for row in data]
    m = [float(row[1]) for row in data]
    result = [[a,b] for a,b in zip(t, m)]

    for line in result:
        print(str(line[0]) + ',' + str(line[1]), file=sys.stdout)

options = 0
if __name__ == "__main__":
    main()

这可能有一些明显的问题,但在研究了所有的元素之后,我一直坚持它正在崩溃的地方。

此外,有可能更好的方法来进行这种类型的csv文件读写,我只是坚持这个,因为我知道做了工作。我知道关于csv模块的例子,但是我找不到任何在命令行中使用它的例子,比如我需要它,我能找到的所有例子都定义了要在脚本本身打开的文件。 / p>

提前谢谢。

2 个答案:

答案 0 :(得分:0)

代码之前的一些事情。如果您使用argparse模块,则必须指定必须接收文件名作为输入。这就是我对add_argument所做的。由于参数不是可选的,因此如果用户未指定文件名,应用程序将退出。

如果用户指定了文件名,我会尝试打开它并创建一个csv阅读器。 csv reader只是一个解析文件的迭代器,所以我可以遍历每一行,我这样做并填充结果列表。当填充列表时,应用程序遍历列表打印出所有元素。 try/except可能出现任何问题。

import io
import csv
import argparse

def main():
    # Create the parser
    parser = argparse.ArgumentParser()
    parser.add_argument('filename', help='Name of the file you want to load')
    args = parser.parse_args()

    result = []
    with io.open(args.filename, 'r', encoding='utf-8') as f:
        reader = csv.reader(f)
        for row in reader:
            result.append([row[0], row[1]])

    for item in result:
        print('{0}, {1}'.format(*item))

if __name__ == "__main__":
    try:
        main()
    except Exception as e:
        print('Something went wrong {0}'.format(e))

答案 1 :(得分:0)

main有效,只需更改print

即可
def main():
    parser = OptionParser()
    options,args = parser.parse_args()
    try:
        data = [(line.rstrip()).split(',') for line in fileinput.input(args)]
    except IOError as detail:
        print(detail, file=sys.stderr)
        sys.exit(2)

    '''kept these lines in just to make sure the data is in the same format as when it worked before'''
    t = [float(row[0]) for row in data]
    m = [float(row[1]) for row in data]
    result = [[a,b] for a,b in zip(t, m)]

    for line in result:
        print(', '.join(str(x) for x in line), file=sys.stdout)

您没有从第二个版本获得任何内容的原因是sys.exit(2)

上的缩进
except IOError as detail:
    print(detail, file=sys.stderr)
sys.exit(2)

退出而不继续正常输出

对argparse进行更正(允许一个或多个输入文件):

def main():
    parser = ArgumentParser()
    parser.add_argument('infiles',nargs='+')
    args = parser.parse_args()
    try:
        data = [(line.rstrip()).split(',') for line in fileinput.input(args.infiles)]
    except IOError as detail:
        print(detail, file=sys.stderr)
        sys.exit(2)

    '''kept these lines in just to make sure the data is in the same format as when it worked before'''
    t = [float(row[0]) for row in data]
    m = [float(row[1]) for row in data]
    result = [[a,b] for a,b in zip(t, m)]

    for line in result:
        print(', '.join(str(x) for x in line))

或者您可以让argparse负责打开文件(并在需要时提出错误):

import argparse
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('infiles',nargs='+', type=argparse.FileType('r'))
    args = parser.parse_args()
    data = [row for file in args.infile for row in csv.reader(file)]

    '''kept these lines in just to make sure the data is in the same format as when it worked before'''
    t = [float(row[0]) for row in data]
    m = [float(row[1]) for row in data]
    result = [[a,b] for a,b in zip(t, m)]

    for line in result:
        print(', '.join(str(x) for x in line))

FileType还将'-'识别为stdin(或('w')文件,stdout