在分隔符处拆分python字符串,但不拆分特定的分隔符 有一种方法来分割Python字符串,而不使用for循环,它基本上将中间的一个字符串分割成最接近的分隔符。

在分隔符处拆分python字符串,但不拆分特定的分隔符 有一种方法来分割Python字符串,而不使用for循环,它基本上将中间的一个字符串分割成最接近的分隔符。,python,Python,比如: 分隔符将是空格,结果字符串将是: The cat jumped over the moon very quickly. 我看到有一个count可以看到其中有多少空格(但看不到如何返回它们的索引)。然后我可以通过除以2来找到中间的一个,但是如何在这个索引的分隔符上说split。Find已关闭,但它返回第一个索引(或使用rfind返回右第一个索引),而不是找到“”的所有索引。我可能想得太多了 我刚分手,然后重新加入: text = "The cat jumped over the moon

比如:

分隔符将是空格,结果字符串将是:

The cat jumped over
the moon very quickly.

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

我刚分手,然后重新加入:

text = "The cat jumped over the moon very quickly"
words = text.split()
first_half = " ".join(words[:len(words)//2])

像这样的怎么样:

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)

我认为使用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.')
这里的想法是:

  • 查找除沫器的索引
  • 找到索引列表的中位数
  • 对此意见分歧
如果您想要得到一半的单词,而不是一半的字符串(计算字符而不是单词),那么使用
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])
在这里,我首先查找带有列表理解的分隔符的索引。然后,我使用内置函数的自定义键找到字符串一半的更接近分隔符的索引。然后分开

print
语句打印
[“猫跳过去了”,“月亮很快了”。]

这应该可以:

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循环可能会有更好的性能


我通过引发一个错误来处理在整个字符串中找不到分隔符
的情况,但更改
raisevalueerror()
以获得您想要处理该情况的任何方式

您可以使用
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)
输出
正如瓦伦蒂诺所说,答案取决于您是希望尽可能平均地分割字符数还是尽可能平均地分割单词数:
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()
的原因是,您可以选择更大的结果,如果字符串只有一侧包含
delim
split()怎么办< /代码>并重新加入结果列表的第一和第二个一半?您定义的算法(计数空格)会将句子拆分成相等数量的单词,这与您的需求冲突(将中间的字符串分割为最接近的分隔符)。你要找哪一个?取决于你是想按#个单词还是整个字符串长度进行拆分。这种拆分是以相等的单词数量进行的,而不是字符。你的意思是
在=text.rfind(“,0,middle)
。从算法上讲,这是最有效的方法。@西班牙人虽然,我认为您必须处理find和rfind将返回-1的情况。该方法将连续的空间折叠为单个空间<代码>“首先␣判决。␣␣及␣然后␣这个␣第二个。“
将首先将字符串拆分为
”␣判决。␣和“
”然后␣这个␣第二个。”
。请注意已折叠的。选项卡
\t
和换行符
\n
合并
时也将转换为单个空格。使用
s.split(“”)
将在每个单独的空格上进行拆分,这将在
合并
合并时保持连续空格,但在将拆分的字符串减半时出现问题。这也会在“一句话有很多很长的单词和很短的单词”不必吹毛求疵,但是
min
调用会消耗一个生成器(即循环)
The cat jumped over
the moon very quickly.
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:])