【问题标题】:GAE Selecting first column of an imported CSVGAE 选择导入的 CSV 的第一列
【发布时间】:2012-12-27 14:34:23
【问题描述】:

我正在将一个简单的 CSV 文件导入到我的 GAE 应用程序中,并且想要选择列表的第一项。下面的代码导入一个 CSV 文件并将每一行保存为一个列表。现在我希望它只显示每个列表项的第一个条目,但如果我使用 data[1] 它表示这超出了范围。我想我错过了一些明显的东西,但似乎无法弄清楚。任何帮助将不胜感激!

class CSVImport(webapp2.RequestHandler):
def post(self):
  csv_file = self.request.get('csv_import')
  fileReader = csv.reader(csv_file.split("\n"))
  dataset = []
  dataset.extend(fileReader)
  for data in dataset:
    self.response.out.write(data)

编辑 1

对于信息,初始代码给出了以下响应:['name', 'description', 'url', 'category', 'deliverycost', 'returning', 'provider', 'prov_id', 'logo' , 'last_update']['Amazon', 'Changed the desc', 'http://www.url.com', 'Meta', '5 Euro', 'Gratis', 'Affilinet', 'Test', ' /images/logos/amazon.jpg', '2012-12-26 13:11:22.519000']['B 店', '', 'http://www.url.com', '', '', '', '', '', '', '2012-12-26 13:19:01.545000']['Otto', 'Test something', 'http://amazon.de', 'Meta', ' ','sdgs','sdgsdg','sdgds','dsgdsg','2012-12-26 13:09:10.716000'][]

根据 RocketDonkey 的回答,我将代码改写为以下内容:

class CSVImport(webapp2.RequestHandler):
def post(self):
   csv_file = self.request.get('csv_import')
   with open(csv_file, 'rb') as f:
      fileReader = csv.reader(f)
      for data in fileReader:
        print data[0]

然而这会产生以下错误:IOError: [Errno 13] file not access: 'name,description,url,category,deliverycost,returning,provider,prov_id,logo,last_update\r\nAmazon,Changed the desc,http ://www.url.com,Meta,5 Euro,Gratis,Affilinet,Test,/im​​ages/logos/amazon.jpg,2012-12-26 13:11:22.519000\r\nB Shop,,http:// www.url.com,,,,,,,2012-12-26 13:19:01.545000\r\nOtto,Test something,http://amazon.de,Meta,,sdgs,sdgsdg,sdgds,dsgdsg,2012 -12-26 13:09:10.716000\r\n'

'accessible:' 之后的内容是 CSV 文件的确切内容,这就是为什么我发现错误“文件不可访问”非常显着。 CSV 文件通过 HTML 表单进入,如下所示:

<form action="/admin/shop/import" method="post" enctype="multipart/form-data">
   <p><strong>Import:</strong>
   <input type="file" name="csv_import" id="csv_import" accept=".csv">
   <input type="submit" value="Import"></p>
</form>

我知道 RemoteAPI 可能是一个更好的解决方案,但是我在 Windows 7 下设置它时遇到了麻烦,这就是我现在尝试构建它作为解决方法的原因。因此,一旦我能够从 CSV 文件的单列中选择数据,我就会将其与我定义的数据库模型进行匹配。

【问题讨论】:

  • 数据的内容是什么?您可以在您的问题中添加一个数据集示例吗?
  • 在描述中添加了数据的内容。谢谢!

标签: python google-app-engine listproperty


【解决方案1】:

编辑:根据您更新的回复,您似乎在csv_file 中获得了实际文件内容,而您的换行符分隔符是\r\n。因此,我建议尝试以下方法:

In [1]: import csv

In [2]: csv_file = # Copied the response from your error into this variable

In [3]: reader = csv.reader(csv_file.split('\r\n'))

In [4]: for row in reader:
   ...:     if row:
   ...:         print row[0]
   ...:         
   ...:         
name
Amazon
B Shop
Otto

if row 检查已完成,因为您可以看到 CSV 字符串的结尾是 \r\n,这意味着当您在 \r\n 字符上拆分时,列表的最后一项将为空。当csv.reader 读取该空元素时,结果是一个空列表,如您所知,如果您尝试按索引进行任何类型的访问,它将失败并显示IndexError。或者,您可以事先执行此操作以确保所有“行”都包含值:

In [8]: csv_file = [row for row in csv_file.split('\r\n') if row]

In [9]: reader = csv.reader(csv_file)

In [10]: for row in reader:
   ....:     print row[0]
   ....:     
   ....:     
name
Amazon
B Shop
Otto

我不确定您的用例,但如果您使用代码将数据上传到您的应用程序,我建议您查看Remote API - 这提供了一种非常简洁的方式来执行此操作并且使您不必使用特殊的处理程序等。

我会假设您传递的是实际的 CSV(不是文件的字符串名称 - 如果您传递的是文件名,请参见下文),因此如下所示:

some_csv = 'header1,header2\nvalue1,value2'

您所做的是在换行符上拆分并传递 csv.reader 一个要迭代的对象,其结果是一个 csv.reader 对象。请注意,您可以直接迭代此对象,因此您无需创建单独的dataset 变量:

In [1]: import csv

In [2]: some_csv = 'header1,header2\nvalue1,value2'

In [3]: fileReader = csv.reader(some_csv.split("\n"))

In [4]: fileReader
Out[4]: <_csv.reader object at 0x1306440>

In [5]: for data in fileReader:
   ...:     print data
   ...:     
   ...:     
['header1', 'header2']
['value1', 'value2']

使用print data[1] 将打印每个列表的第二项(如@sadaf2605 所述,Python 使用从零开始的索引,因此第一个元素实际上是data[0])。您的错误表明每行只有一个元素,因此首先要检查的是您是否实际上将逗号分隔的值传递给该参数。

但是您还提到您正在导入 CSV 文件 - 您的 URL 参数是对文件名本身的字符串引用吗?如果是这样,那将导致问题,因为您实际上不会打开文件 - 您将迭代一个仅包含文件本身名称的对象,而不是数据:

In [1]: import csv

In [2]: some_csv = 'some_csv.csv'

In [3]: fileReader = csv.reader(some_csv.split("\n"))

In [4]: for data in fileReader:
   ...:     print data
   ...:     
   ...:     
['some_csv.csv']

再次从零开始索引,您可以看到该数组没有第二个元素,因此您将获得IndexError。如果这是你的情况,你可以试试这个(虽然我会再次建议远程 API :))

In [1]: import csv

In [2]: some_csv = 'some_csv.csv'

In [3]: with open(some_csv, 'rb') as f:
   ...:     fileReader = csv.reader(f)
   ...:     for data in fileReader:
   ...:         print data[0]
   ...:         
   ...:         
header1
value1

【讨论】:

  • 我最后尝试了这个建议,但它给出了一个我无法解释的不同错误。我在描述中添加了详细信息。感谢您的建议!
  • @Vincent Ah,所以这个错误是因为你试图打开一个文件,但你已经有了内容。与其尝试打开文件,不如尝试将csv_file 直接传递给csv.reader(没有with,也没有split)。 reader 将正确解释换行符而无需拆分,因此它应该可以正常处理。一旦我在电脑前,我会更新我的答案以反映您的数据。
  • @Vincent 我添加了一个更新,我相信它可能会让您走上正轨——如果不是,很乐意帮助您解决问题。另外,如果您愿意,我们可以进行聊天并尝试解决 Remote API - 在偶然发现它并看到它有多棒之后,我发誓我永远不会回去,非常乐意提供帮助:)
  • 非常感谢 RocketDonkey,你成就了我的一天!现在就像一个魅力。关于远程 API,我也非常感谢您的提议。然而,问题是我没有使用解释器(从未学会如何做到这一点),因此我无法运行 appcfg.py。在浪费您的时间之前,我将首先看看我是否可以通过学习如何与 GAE 上的口译员一起工作来解决这个问题。再次感谢,非常感谢!
  • @Vincent 没问题,乐于助人!听起来像一个计划 - 我对命令行之外的环境不是很熟悉,所以无论如何我在这方面可能一文不值:)祝一切顺利!
【解决方案2】:

在python中,数组从0...n-1开始,所以当你试图只显示每个列表项的第一个条目时,你肯定应该使用array[0],它不应该是data[1]无论如何。

【讨论】:

  • 谢谢萨达夫。实际上我也尝试了 data[0] 并且它给出了同样的错误。
猜你喜欢
  • 2019-06-10
  • 1970-01-01
  • 2013-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-29
  • 1970-01-01
相关资源
最近更新 更多