有没有更好的方法从Python中的文件中读取元素?

时间:2011-10-05 16:02:51

标签: python list csv

我编写了一个粗略的Python程序,用于从CSV文件中的索引中提取短语,并将这些行写入另一个文件。

import csv

total = 0

ifile = open('data.csv', "rb")
reader = csv.reader(ifile)

ofile = open('newdata_write.csv', "wb")
writer = csv.writer(ofile, delimiter='\t', quotechar='"', quoting=csv.QUOTE_ALL)

for row in reader:
    if ("some text") in row[x]:
        total = total + 1
        writer.writerow(row)
    elif ("some more text") in row[x]:
        total = total + 1   
        writer.writerow(row) 
    elif ("even more text I'm looking for") in row[x]:  
        total = total + 1   
        writer.writerow(row)

   < many, many more lines >

print "\nTotal = %d." % total

ifile.close()

我的问题是:是不是有更好的(更优雅/更简洁)Pythonic方式来做到这一点?我觉得这是一个不知道我不知道的情况。我正在搜索的CSV文件不大(3863行,669 KB),所以我认为没有必要使用SQL to solve this,尽管我当然对此持开放态度。

我是一名Python新手,热爱语言并通过正常渠道(书籍,教程,Project Euler,Stack Overflow)自学。

非常感谢任何建议。

5 个答案:

答案 0 :(得分:6)

您正在寻找带有生成器表达式的any

matches = "some text", "some more text", "even more text I'm looking for"
for row in reader:
    if any(match in row for match in matches):  
        total += 1   
        writer.writerow(row)

或者,您可以一次写下所有行:

writer.writerows(row for row in reader if any(match in row for match in matches))

但正如所写,并没有给你一个总数。

答案 1 :(得分:1)

这不是一个巨大的改进,但你可以做点像

keyphraseList = (
     "some text",
     "some more text",
     "even more text I'm looking for")

...
for row in reader:
   for phrase in keyphraseList:
       if phrase in row[x]:
           total = total + 1
           writer.writerow(row)
           break

(未经测试)

答案 2 :(得分:0)

没有必要,'更好',但我会将项目与一组进行比较并清理一下总数。它可能不是“更好”,但它更简洁

for row in reader:
    if ("some text") in row[x]:
        total = total + 1
        writer.writerow(row)
    elif ("some more text") in row[x]:
        total = total + 1   
        writer.writerow(row) 
    elif ("even more text I'm looking for") in row[x]:  
        total = total + 1   
        writer.writerow(row)

变为

myWords = set(('some text','some more text','even more'))
for row in reader:
     if row[x] in myWords: 
          total += 1
          writer.writerow(row)

你可以使用一个简单的列表,但是在更多内存密集型任务上设置会更快。

回应agf的评论

>>> x = set(('something','something else'))
>>> Ture if 'some' in x else False
False
>>> True if 'something' in x else False
True

这是你的说法不起作用吗?

答案 3 :(得分:0)

你可以使用列表推导而不是for循环来获得pythonic。例如,如果您要查找索引字符串'aa'或'bb',则可以执行

matches = [row for row in reader if 'aa' in row[0] or 'bb' in row[0]]

答案 4 :(得分:0)

我不确定这个版本是否更好,只是更短,无论如何希望它有帮助

import csv

total = 0

keys = ['a', 'b', 'c']
with open('infile', 'rb') as infile, open('outfile', 'wb') as outfile:
    rows = [x for x in csv.reader(infile) if any([k in x[0] for k in keys])]
    csv.writer(outfile, delimiter='\t', quotechar='"', quoting=csv.QUOTE_ALL).writerows(rows)

print 'Total: %d' % len(rows)