所需的任务是提取包含x个y出现次数的行。输入文本文件包含1,000,000行,每行50-200个字符。
在这种情况下,假设包含20个空格的行。有更多的pythonic方式吗?目前,我这样做:
import codecs
def readlinesmorethan20spaces(intxtfile):
with codecs.open(intxtfile, 'r','utf8') as fin:
for i in fin:
if i.count(" ") > 20:
yield i.strip()
for i in readlinesmorethan20spaces("in.txt"):
print i
如果没有python但是使用unix命令怎么办呢?它甚至可能吗?
答案 0 :(得分:4)
使用grep和sed的Unix方式:
grep -E '(\s[^\s]*){20,}' in.txt | sed 's/^\s*//;s/\s*$//'
第一个命令过滤具有20+个空格(甚至非连续)的行,然后第二个命令剥离前导和尾随空格。
这不是一种理想的方法,它可能比其他方法慢(awk也许),但它很简单。顺便说一句,我对本页提到的不同方法的性能比较感兴趣...
是的,几乎所有东西都可以用正则表达式解决! ;)
答案 1 :(得分:0)
列表组件通常更加pythonic。在您的上下文中,它看起来像这样:
import codecs, re
def readlinesmorethan20spaces(intxtfile):
with codecs.open(intxtfile, 'r','utf8') as fin:
return (i.strip() for i in fin if i.count(' ') > 20)
for i in readlinesmorethan20spaces("in.txt"):
print i
在这种情况下,返回生成器与之前的yield
语句类似。
如果您愿意,也可以将其作为一行进行,但我认为上述版本更具可读性:
read_lines = lambda fn: (i.strip() for i in codecs.open(fn, 'r', 'utf8') if i.count(' ') > 20)
unix方法不太直接,但这应该是完全可能的。开始可能是使用awk
来计算每行中的字符。这是一个例子:
awk -v FS=""'{cnt=0;for (i=1;i<=NF;i++) if ($i==" ") cnt++; print cnt"\t"NR}' stores.dat
答案 2 :(得分:0)
我通常不会打扰发电机
import codecs
with codecs.open(intxtfile, 'r','utf8') as fin:
for i in fin:
if i.count(' ') <= 20:
continue
i = i.strip()
...
使用函数/生成器的一个优点是单元测试的细粒度组件。正如评论中所提到的那样 - 稍微移动一下会使生成器更容易测试,因为fin
不需要是一个打开的文件 - 它同样可以是一个列表等。
import codecs
def readlinesmorethan20spaces(fin):
for i in fin:
if i.count(" ") > 20:
yield i.strip()
with codecs.open(intxtfile, 'r','utf8') as fin:
for i in readlinesmorethan20spaces(fin):
print i
答案 3 :(得分:0)
使用高性能容器collections.Counter的其他方式:
import codecs
import collections
def readlinesmorethan20spaces(intxtfile):
with codecs.open(intxtfile, 'r','utf8') as fin:
for line in fin:
counter = collections.Counter(line)
if counter[" "] > 20:
yield line.strip()
for i in readlinesmorethan20spaces("in.txt"):
print i