我正在处理一个大文本文件,作为输出,我有一个单词列表:
['today', ',', 'is', 'cold', 'outside', '2013', '?', 'December', ...]
我接下来想要实现的是将所有内容转换为小写,删除属于stopset的所有单词(常用单词)并删除标点符号。我可以通过3次迭代来做到这一点:
lower=[word.lower() for word in mywords]
removepunc=[word for word in lower if word not in string.punctuation]
final=[word for word in removepunc if word not in stopset]
我尝试使用
[word for word in lower if word not in string.punctuation or word not in stopset]
实现最后2行代码应该做的但是它不起作用。我的错误在哪里,有没有更快的方法来实现这一点,而不是遍历列表3次?
答案 0 :(得分:2)
如果您的代码按预期工作,我认为这不是一个好主意。现在它具有良好的可读性,可以通过其他处理轻松修改。单行是有利于获得更多的投票,你将很难在一段时间后理解它的逻辑。
您可以使用生成器而不是列表替换中间步骤,以使计算工作一次,而不是生成多个列表:
lower = (word.lower() for word in mywords)
removepunc = (word for word in lower if word not in string.punctuation)
final = [word for word in removepunc if word not in stopset]
答案 1 :(得分:1)
你当然可以压缩逻辑:
final = [word for word in map(str.lower, mywords)
if word not in string.punctuation and word not in stopset]
例如,如果我定义stopset = ['if']
,我会得到:
['today', 'cold', 'outside', '2013', 'december']
答案 2 :(得分:0)
这是相同的单一列表理解,虽然我同意烷基,你已经拥有的东西更清楚:
final = [lower_word for word in mywords for lower_word in (word.lower(),) if lower_word not in string.punction and lower_word not in stopset]
答案 3 :(得分:0)
请注意,列表推导不是大文件的最佳选择,因为整个文件必须加载到内存中。
而是做Read large text files in Python, line by line without loading it in to memory
之类的事情with open("log.txt") as infile:
for line in infile:
if clause goes here:
....
答案 4 :(得分:0)
我猜最快的方法是尝试尽可能多地将计算从Python移动到C.首先预先计算禁用字符串集。这只需要完成一次。
avoid = set(string.punctuation) | set(x.lower() for x in stopset)
然后让set减法操作尽可能多地进行过滤
final = set(x.lower() for x in mywords) - avoid
在开始之前将整个单词源一次转换为小写也可能会提高速度。在这种情况下,代码将是
final = set(mywords) - avoid
答案 5 :(得分:0)
您可以使用map
折叠.lower
处理
final = [word for word in map(str.lower, mywords) if word not in string.punctuation and word not in stopset]
您只需将string.punctuation
添加到stopset
,然后就会变为
final = [word for word in map(str.lower, mywords) if word not in stopset]
您确定不想保留输出中单词的大小写吗?
答案 6 :(得分:0)
有没有更快的方法来实现这一点,而不是迭代 列出3次?
将johnsharpe的代码转换为生成器。这可能会大大加快使用速度并降低内存使用量。
import string
stopset = ['is']
mywords = ['today', ',', 'is', 'cold', 'outside', '2013', '?', 'December']
final = (word.lower() for word in mywords if (word not in string.punctuation and
word not in stopset))
print "final", list(final)
要在迭代器之外显示调试结果,请使用此示例中的list
答案 7 :(得分:0)
如果你使用过滤器,你可以使用一个列表理解来实现它,并且更容易阅读。
final = filter( lambda s: s not in string.punctation and s not in stopset ,[word.lower() for word in mywords])