我需要将字符串拆分成单词,然后成对连接每个连续的单词,如下所示:
"This is my subject string"
会去:
"This is"
"is my"
"my subject"
"subject string"
字符串的长度从 5 个字到 250 个字不等。此外,它会在大量数据(1GB 左右)上执行此操作。在 Python 中有没有一种有效的方法来做到这一点?
我已经看到很多关于哪种方法最有效的建议,所以想先问一下。
我需要将字符串拆分成单词,然后成对连接每个连续的单词,如下所示:
"This is my subject string"
会去:
"This is"
"is my"
"my subject"
"subject string"
字符串的长度从 5 个字到 250 个字不等。此外,它会在大量数据(1GB 左右)上执行此操作。在 Python 中有没有一种有效的方法来做到这一点?
我已经看到很多关于哪种方法最有效的建议,所以想先问一下。
您可以使用 split 方法和列表推导来做到这一点:
text = "This is my subject string"
words = text.split() #note that split without arguments splits on whitespace
pairs = [words[i]+' '+words[i+1] for i in range(len(words)-1)]
print(pairs)
有一个itertools
名为pairwise的食谱就是为此而建的!不使用它会很疯狂。
>>> from itertools import tee, izip
>>> def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return izip(a, b)
>>> list(pairwise(text.split()))
[('This', 'is'), ('is', 'my'), ('my', 'subject'), ('subject', 'string')]
这是 Pythonic 方式
from itertools import izip
[' '.join(pair) for pair in izip(words[:-1], words[1:])]
izip将保持或多或少的效率
>>> import re
>>> text = "This is my subject string"
>>> re.findall(r'(\w+)\s+(?=(\w+))', text)
[('This', 'is'), ('is', 'my'), ('my', 'subject'), ('subject', 'string')]
如果您需要一个生成器,只需使用re.finditer
pairs = (m.groups() for m in re.finditer(r'(\w+)\s+(?=(\w+))', text))
这是非常快速/高效的,第二个版本将是最有效的,因为它不会一次将所有单词存储在内存中,但是它不会那么快。您必须分析向您建议的方法,以查看哪种方法适合您。
在这种情况下,天真的实现应该可以正常工作,假设每个字符串都很小(不是 1GB)
string = "This is my subject string"
words = string.split()
prevWord = None
for word in words:
if prevWord != None:
print prevWord, word
prevWord = word
像往常一样,在处理相当大的数据集时,您需要读取一个项目,处理它,读取下一个项目等。不要尝试split()
整个文件。
如果您不介意计算初始列表的长度,那么您可以执行以下操作:
s = 'this is a test string'.split()
n = len(s)
for first, second in itertools.izip(itertools.islice(s, 0, n-1), itertools.islice(s, 1, n)):
print(first, second)
这输出:
('this', 'is')
('is', 'a')
('a', 'test')
('test', 'string')
这对于大量数据应该是有效的,因为您没有创建一个巨大的列表(除了您已经拥有的)。