代码之家  ›  专栏  ›  技术社区  ›  Codejoy

在分隔符但特定的分隔符处拆分python字符串

  •  4
  • Codejoy  · 技术社区  · 6 年前

    有没有一种方法可以在不使用for循环的情况下拆分python字符串,该循环基本上将中间的字符串拆分为最接近的分隔符。

    像:

    The cat jumped over the moon very quickly.
    

    分隔符为空格,生成的字符串为:

    The cat jumped over
    the moon very quickly.
    

    我看到有一个 count 我可以看到其中有多少个空间(但不知道如何返回它们的索引)。然后我可以通过除以2找到中间的一个,但是如何在这个索引处的分隔符上说split。find是关闭的,但它返回第一个索引(或使用rfind右一个索引),而不是找到“”的所有索引。我可能想得太多了。

    7 回复  |  直到 6 年前
        1
  •  1
  •   LonelyDaoist    6 年前

    像这样的怎么样:

    s = "The cat jumped over the moon very quickly"
    
    l = s.split()
    
    s1 = ' '.join(l[:len(l)//2])
    s2 = ' '.join(l[len(l)//2 :])
    
    print(s1)
    print(s2)
    
        2
  •  5
  •   Olivier Melançon iacob    6 年前

    这应该有效:

    def split_text(text):
        middle = len(text)//2
        under = text.rfind(" ", 0, middle)
        over = text.find(" ", middle)
        if over > under and under != -1:
            return (text[:,middle - under], text[middle - under,:])
        else:
            if over is -1:
                  raise ValueError("No separator found in text '{}'".format(text))
            return (text[:,middle + over], text[middle + over,:])
    

    它不使用for循环,但使用for循环可能会有更好的性能。

    我负责处理分离机 不是通过引发错误在整个字符串中找到的,而是更改 raise ValueError() 不管你想用什么方式处理这个案子。

        3
  •  4
  •   Olivier Melançon iacob    6 年前

    你可以使用 min 找到最靠近中间的空间,然后切片字符串。

    s = "The cat jumped over the moon very quickly."
    
    mid = min((i for i, c in enumerate(s) if c == ' '), key=lambda i: abs(i - len(s) // 2))
    
    fst, snd = s[:mid], s[mid+1:]
    
    print(fst)
    print(snd)
    

    产量

    The cat jumped over
    the moon very quickly.
    
        4
  •  2
  •   Joe Halliwell    6 年前

    我只是分开然后重新加入:

    text = "The cat jumped over the moon very quickly"
    words = text.split()
    first_half = " ".join(words[:len(words)//2])
    
        5
  •  2
  •   Charles Landau    6 年前

    我认为使用split的解决方案是好的。我试图解决它没有 split 这就是我想到的。

    sOdd = "The cat jumped over the moon very quickly."
    sEven = "The cat jumped over the moon very quickly now."
    
    def split_on_delim_mid(s, delim=" "):
      delim_indexes = [
          x[0] for x in enumerate(s) if x[1]==delim
      ] # [3, 7, 14, 19, 23, 28, 33]
    
      # Select the correct number from delim_indexes
      middle = len(delim_indexes)/2
      if middle % 2 == 0:
        middle_index = middle
      else:
        middle_index = (middle-.5)
    
      # Return the separated sentances
      sep = delim_indexes[int(middle_index)]
      return s[:sep], s[sep:]
    
    split_on_delim_mid(sOdd) # ('The cat jumped over', ' the moon very quickly.')
    split_on_delim_mid(sEven) # ('The cat jumped over the', ' moon very quickly now.')
    

    这里的想法是:

    • 找出除沫器的指标。
    • 找到索引列表的中位数
    • 就此分手。
        6
  •  1
  •   Valentino    6 年前

    解决方案 split() join() 如果你想得到一半的单词,而不是一半的字符串(计算字符而不是单词),就可以了。我认为如果没有 for 循环或列表理解(或者为查找空间索引而进行的这种递归的昂贵解决方案)。

    但是如果你对清单的理解很好,你可以做到:

    phrase = "The cat jumped over the moon very quickly."
    
    #indexes of separator, here the ' '
    sep_idxs = [i for i, j in enumerate(phrase) if j == ' ']
    
    #getting the separator index closer to half the length of the string
    sep = min(sep_idxs, key=lambda x:abs(x-(len(phrase) // 2)))
    
    first_half = phrase[:sep]
    last_half = phrase[sep+1:]
    
    print([first_half, last_half])
    

    在这里,我首先查找具有列表理解的分隔符的索引。然后,我使用自定义键查找靠近字符串一半的分隔符的索引。 min() 内置功能。然后分裂。

    这个 print 报表打印 ['The cat jumped over', 'the moon very quickly.']

        7
  •  0
  •   Especially Lime    6 年前

    正如瓦伦蒂诺所说,答案取决于您是希望尽可能均匀地拆分字符数,还是尽可能均匀地拆分单词数: split() -基于方法将实现后者。

    这是一种不需要循环或列表理解就可以完成前者的方法。 delim 可以是任何单个字符。如果您想要更长的分隔符,这个方法就不能工作,因为在这种情况下,它不需要完全在前半部分或者完全在后半部分。

    def middlesplit(s,delim=" "):
        if delim not in s:
            return (s,)
        midpoint=(len(s)+1)//2
        left=s[:midpoint].rfind(delim)
        right=s[:midpoint-1:-1].rfind(delim)    
        if right>left:
            return (s[:-right-1],s[-right:])
        else:
            return (s[:left],s[left+1:])
    

    使用原因 rfind() 而不是 find() 是为了让你可以选择更大的结果,确保你避免 -1 如果字符串的一侧包含 德莱姆 .