2015-08-31 71 views
1

我的工作分配在Python类目前列出的元组,以及一个特定部分要求我在“文本的格式导入CSV文件(数据,数字,数字,...,数字,数字“),并且以这种格式返回数据作为元组列表:解析CSV不使用CSV模块

[(’Text’, [number, number, ..., number, number]), 
(’Text’, [number, number, ..., number, number]), 
.....] 
[(’Text’, [number, number, ..., number, number]), 
(’Text’, [number, number, ..., number, number]), 
.....] 

我想我得打开文件,并开始由线正确路线读它(见下面代码段)的实际过程,但我不能就如何处理方面着手每行解析成格式相当肯定需要。

def load_data(filename): 
    open(filename) 
    for line in filename 

我试图寻找帮助,但唯一的帮助,我似乎找到说只使用CSV模块(这是不是特别有帮助,因为我们不允许任何导入模块吧数学库)或者以不同格式输入和/或输出数据。如果任何人都可以给我一些关于我应该做什么的指示,或者我可以在哪里开始,这将是超级有用的。谢谢!

编辑:每通过@dotancohen这里提出的建议是一些示例数据:

Slow Loris, 21.72, 29.3, 20.08, 29.98, 29.85, 26.22, 29.68 
Ocelot, 57.51, 47.59, 55.89, 47.15, 46.71, 51.7, 46.68, 54.54 
Tiger, 75.0, 82.43, 112.11, 89.93, 103.19, 80.6, 113.44, 75.55, 102.29, 108.1, 98.84, 101.48, 77.75, 98.57, 70.31, 78.28, 80.18 

而且下面是我目前所面对的是一个潜在的解决方案:

def load_data(filename): 
    open(filename) as file 
    output = [] 
    for line in filename 
     temp_list = line.split(',') 
     temp_item = temp_list.pop(0) 
     tup = (temp_item, temp_list) 
     output.append(tup) 
    return output 

回答

2

CSV文件通常有逗号或制表符分隔的线,所以在天真情况下,这会给你不同的领域:

for line in filename: 
    fields = line.split(',') # For comma-delimited files 
    # - or - 
    fields = line.split('\t') # For tab-delimited files 

然而,我们很少能够让自己成为很天真。 CSV文件中,除其他外,要注意以下几点:

  1. 引用的值:这是一个CSV法律领域:“我思故我在”。你需要小心,不要在引号内的逗号分割。 Newines也可以出现在引用的值中,所以你不能可靠地使用for line in filename
  2. 转义引号引用中值:这是一个CSV法律领域:“她说:\”我也这么认为\“”。这意味着你的状态机匹配每个字符的引号外引号的状态也需要一个回顾机制。

因此,为了可靠地解析CSV文件,您需要一个能够跨文件保存状态的状态机。一路上有可怕的惊喜,比如在Python 2中处理Unicode CSV文件(提示:如果你有非ASCII文本,请使用Python 3)。还有一些小惊喜,如某些应用程序在逗号分隔符之后放置空格,或者不在行尾添加空白字段的逗号。

因此,如果您要将接受来自用户的CSV输入文件,请使用CSV模块。然而,如果能控制输入(即,从其他脚本产生它),那么就可以使用幼稚line.split('\t')方法。

根据OP公布的样本数据,我们看到他不必担心引用字段,但他的CSV源实际上在逗号分隔符之后添加了错误的空格。因此,这是具体到OP的情况代码:

for line in filename: 
    fields = line.split(',') 
    fields = [x.strip() for x in fields] # Remove whitespace 
+0

对,所以我会使用line.split(','),因为我的文件完全是用逗号分隔的。尽管我无法控制输入,但我们已经获得了两个CSV文件,程序将针对这两个文件进行测试,并且它们都具有相同的一致格式,而且没有引号值,转义引号或非Unicode字符(尽管我们正在使用Python 3)。我应该将文本分割成单独的变量,然后将文本作为元组重新加入数字中?这应该给我所寻找的输出,对不对? – RandosaurusRex

+0

@RandosaurusRex - 这看起来是一段很好的工作方法。你可能没有进一步的帮助就可以完成它,但如果你尝试这种设计,并且麻烦回来并要求详细的帮助。我怀疑你会从这里得到好处,但如果你确实遇到了从这里到最后的跳闸点,那么不会感到羞耻。 – jwpfox

+0

@RandosaurusRex:我希望在给出yes或no之前查看示例文件,能否请您在问题中添加几行示例行?谢谢。 – dotancohen

1

的一个关键概念看看会是split()

根据逗号拆分CSV似乎是拼图的重要组成部分,你不同意。

+0

所以我要使用的东西沿着line.split的线条来替换这一行lst = zip(x,y)( '') ?如果我这样做,我应该做一些事情,如将列表分成两个子列表,一个与文本和另一个与数字,然后以某种方式将它们链接为单个列表项目? – RandosaurusRex

0

这是CSV文件data

text1 1 2 3 4 5 
text2 6 7 8 9 10 
text3 11 12 13 14 15 

您可以使用setdefaultzip实现了输出你Python2需要

d = {} 
with open('your_file.csv', 'rb') as f: 
    for line in f: 
     line = line.split() 
     for i in line[1:]: 
      key = (line[0]) 
      d.setdefault(key, []).append(int(i)) 

x = sorted(d.keys()) 
y = sorted(d.values()) 
lst = zip(x,y) 
print (lst) 

输出:

[('text1', [1, 2, 3, 4, 5]), ('text2', [6, 7, 8, 9, 10]), ('text3', [11, 12, 13, 14, 15])] 

Python3你有lst = list(zip(x,y))