【问题标题】:Create Consecutive Two Word Phrases from String从字符串创建连续的两个单词短语
【发布时间】:2020-08-16 10:29:08
【问题描述】:

我花了难以置信的时间试图寻找一种方法来使用 itertools 将句子转换为两个单词的短语列表。

我要拍这个:“敏捷的棕狐”

然后把它变成这样:“the quick”,“quick brown”,“brown fox”

我尝试过的所有内容都可以返回从单个单词到 4 个单词列表的所有内容,但没有任何内容只返回对。

我已经尝试了 itertools 组合的多种不同用法,我知道这是可行的,但我无法找出正确的组合,我不想为某些东西定义函数我知道只需两行或更少的代码即可。谁能帮帮我?

【问题讨论】:

标签: python python-3.x combinations itertools


【解决方案1】:

如果您想要一个纯迭代器解决方案来处理具有恒定内存使用的大字符串:

input       = "the quick brown fox"
input_iter1 = map(lambda m: m.group(0), re.finditer(r"[^\s]+", input))                                                                                                                     
input_iter2 = map(lambda m: m.group(0), re.finditer(r"[^\s]+", input))                                                                                                                     
next(input_iter2) # skip first
output = itertools.starmap(
    lambda a, b: f"{a} {b}", 
    zip(input_iter1, input_iter2)
)
list(output)                                                         
# ['the quick', 'quick brown', 'brown fox']

如果您有额外的 3 倍字符串内存来将 split() 和加倍输出存储为列表,那么不使用 itertools 可能会更快更容易:

inputs = "the quick brown fox".split(' ')    

output = [ f"{inputs[i]} {inputs[i+1]}" for i in range(len(inputs)-1) ] 
#  ['the quick', 'quick brown', 'brown fox']

更新

支持任意 ngram 大小的通用解决方案:

from typing import Iterable  
import itertools

def ngrams_iter(input: str, ngram_size: int, token_regex=r"[^\s]+") -> Iterable[str]:
    input_iters = [ 
        map(lambda m: m.group(0), re.finditer(token_regex, input)) 
        for n in range(ngram_size) 
    ]
    # Skip first words
    for n in range(1, ngram_size): list(map(next, input_iters[n:]))  

    output_iter = itertools.starmap( 
        lambda *args: " ".join(args),  
        zip(*input_iters) 
    ) 
    return output_iter

测试:

input = "If you want a pure iterator solution for large strings with constant memory usage"
list(ngrams_iter(input, 5))

输出:

['If you want a pure',
 'you want a pure iterator',
 'want a pure iterator solution',
 'a pure iterator solution for',
 'pure iterator solution for large',
 'iterator solution for large strings',
 'solution for large strings with',
 'for large strings with constant',
 'large strings with constant memory',
 'strings with constant memory usage']

你也可以找到这个相关的问题:n-grams in python, four, five, six grams?

【讨论】:

    【解决方案2】:

    @DarrylG 答案似乎是要走的路,但你也可以使用:

    s = "the quick brown fox"
    p  = s.split()
    ns = [f"{w} {p[n+1]}" for n, w in enumerate(p) if n<len(p)-1 ]
    # ['the quick', 'quick brown', 'brown fox']
    

    Demo

    【讨论】:

      【解决方案3】:

      试试:

      s = "the quick brown fox"
      words = s.split()
      result = [' '.join(pair) for pair in zip(words, words[1:])]
      print(result)
      

      输出

      ['the quick', 'quick brown', 'brown fox']
      

      说明

      使用zip为词对创建迭代器

      zip(words, words[1:]
      

      迭代对

      for pair in zip(words, words[1:])
      

      创建结果词

      [' '.join(pair) for ...]
      

      【讨论】:

      • 那太好了,我什至不必使用 itertools。谢谢!
      猜你喜欢
      • 1970-01-01
      • 2014-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-09
      • 1970-01-01
      • 2011-09-18
      • 1970-01-01
      相关资源
      最近更新 更多