Python 对所有并排单词成对拆分字符串单词

Python 对所有并排单词成对拆分字符串单词,python,Python,我需要将字符串拆分为单词,然后将每个连续的单词成对连接起来,如下所示: "This is my subject string" 将转到: "This is" "is my" "my subject" "subject string" 字符串的大小从5个单词到250个单词不等。而且,它将在大量数据上执行此操作,1GB左右。在Python中有没有一种有效的方法来实现这一点 我看到了很多关于哪些方法最有效的建议,所以我想先问一下。您可以使用拆分方法并列出理解: text =

我需要将字符串拆分为单词,然后将每个连续的单词成对连接起来,如下所示:

"This is my subject string"  
将转到:

"This is"    
"is my"  
"my subject"  
"subject string" 
字符串的大小从5个单词到250个单词不等。而且,它将在大量数据上执行此操作,1GB左右。在Python中有没有一种有效的方法来实现这一点


我看到了很多关于哪些方法最有效的建议,所以我想先问一下。

您可以使用拆分方法并列出理解:

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)
这是蟒蛇式的方式

from itertools import izip
[' '.join(pair) for pair in izip(words[:-1], words[1:])]

izip将或多或少地保持它的效率

在这种情况下,假设每个字符串都很小(而不是1GB),朴素的实现应该可以很好地工作


与往常一样,在处理一个相当大的数据集时,您需要读取一个项目、处理它、读取下一个项目等。不要尝试
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')
这对于大量数据来说应该是有效的,因为您没有创建一个庞大的列表(除了您已经拥有的列表之外)。

有一个专门为此构建的列表!你要是不使用它就疯了

>>> 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')]
如果您需要一个生成器,只需使用
re.finditer

pairs = (m.groups() for m in re.finditer(r'(\w+)\s+(?=(\w+))', text))

这是非常快速/高效的,第二个版本将是最高效的,因为它不会一次将所有单词存储在内存中,但是它不会那么快。您必须对建议的方法进行分析,以确定哪种方法适合您。

到目前为止您尝试了哪些方法?处理1GB有哪些限制(内存、时间等)?拆分如何公平处理大数据?它不会返回生成器afaik。它不会,但是字符串中的250个单词应该不会有问题。瓶颈是列表理解,但它可以根据需求合理化。是的,我误读了这个问题,我认为他的字符串应该是1GB左右。@gatto将其制作成一个生成器涉及到用列表中的
[]
替换
()
。或者你说的是拆分成单词的过程吗?我说的是
str.split
。我只是好奇-为什么要投反对票?我没有投反对票,但你列出了两个列表(
words[:-1]
words[1://code>)。@Alok-对于250个单词的句子,这不算什么overhead@volcano请参阅我的解决方案,以获得最有效的原始速度,可能不是最快的,但它不会创建两个副本lists@jamylak-确实很好,值得学习。我对迭代(ugh)指示的解决方案有问题,你能解释第一行
“s->(s0,s1),…
@masfenix这只是docstring,它是结果的可视化表示,例如(elem0,elem1),(elem1,elem2),等等。好的,谢谢,你能逐行介绍一下你的函数吗。我正在学习python,我很困惑。@masfenix
tee
复制了一个迭代器,
next(b,无)
b
向前推进一项。然后将
izip
两个迭代器放在一起,因此每对迭代器将有
a
b
中的一个元素,但是
b
的元素将比athip中的元素提前一个。这与我的想法非常接近,但对于Python来说非常陌生,我不知道是否有赌注还有,弦本身会很小。
>>> import re
>>> text = "This is my subject string"
>>> re.findall(r'(\w+)\s+(?=(\w+))', text)
[('This', 'is'), ('is', 'my'), ('my', 'subject'), ('subject', 'string')]
pairs = (m.groups() for m in re.finditer(r'(\w+)\s+(?=(\w+))', text))