Есть ли способ разделить строку на каждый n-й разделитель в Python? - PullRequest
14 голосов
/ 25 октября 2009

Например, если у меня была следующая строка:

"это-это-строка"

Могу ли я разделить его на каждое второе "-", а не на каждое "-", чтобы оно возвращало два значения ("это-есть" и "строка-а"), а не возвращало четыре?

Ответы [ 6 ]

36 голосов
/ 25 октября 2009

Вот еще одно решение:

span = 2
words = "this-is-a-string".split("-")
print ["-".join(words[i:i+span]) for i in range(0, len(words), span)]
16 голосов
/ 25 октября 2009
>>> s="a-b-c-d-e-f-g-h-i-j-k-l"         # use zip(*[i]*n)
>>> i=iter(s.split('-'))                # for the nth case    
>>> map("-".join,zip(i,i))    
['a-b', 'c-d', 'e-f', 'g-h', 'i-j', 'k-l']

>>> i=iter(s.split('-'))
>>> map("-".join,zip(*[i]*3))
['a-b-c', 'd-e-f', 'g-h-i', 'j-k-l']
>>> i=iter(s.split('-'))
>>> map("-".join,zip(*[i]*4))
['a-b-c-d', 'e-f-g-h', 'i-j-k-l']

Иногда itertools.izip работает быстрее, как видно из результатов

>>> from itertools import izip
>>> s="a-b-c-d-e-f-g-h-i-j-k-l"
>>> i=iter(s.split("-"))
>>> ["-".join(x) for x in izip(i,i)]
['a-b', 'c-d', 'e-f', 'g-h', 'i-j', 'k-l']

Вот версия, которая вроде работает с нечетным количеством деталей, в зависимости от того, какой вывод вы хотите в этом случае. Вы можете предпочесть обрезать '-' на конце последнего элемента, например, .rstrip('-').

>>> from itertools import izip_longest
>>> s="a-b-c-d-e-f-g-h-i-j-k-l-m"
>>> i=iter(s.split('-'))
>>> map("-".join,izip_longest(i,i,fillvalue=""))
['a-b', 'c-d', 'e-f', 'g-h', 'i-j', 'k-l', 'm-']

Вот некоторые времена

$ python -m timeit -s 'import re;r=re.compile("[^-]+-[^-]+");s="a-b-c-d-e-f-g-h-i-j-k-l"' 'r.findall(s)'
100000 loops, best of 3: 4.31 usec per loop

$ python -m timeit -s 'from itertools import izip;s="a-b-c-d-e-f-g-h-i-j-k-l"' 'i=iter(s.split("-"));["-".join(x) for x in izip(i,i)]'
100000 loops, best of 3: 5.41 usec per loop

$ python -m timeit -s 's="a-b-c-d-e-f-g-h-i-j-k-l"' 'i=iter(s.split("-"));["-".join(x) for x in zip(i,i)]'
100000 loops, best of 3: 7.3 usec per loop

$ python -m timeit -s 's="a-b-c-d-e-f-g-h-i-j-k-l"' 't=s.split("-");["-".join(t[i:i+2]) for i in range(0, len(t), 2)]'
100000 loops, best of 3: 7.49 usec per loop

$ python -m timeit -s 's="a-b-c-d-e-f-g-h-i-j-k-l"' '["-".join([x,y]) for x,y in zip(s.split("-")[::2], s.split("-")[1::2])]'
100000 loops, best of 3: 9.51 usec per loop
9 голосов
/ 25 октября 2009

Регулярные выражения обрабатывают это легко:

import re
s = "aaaa-aa-bbbb-bb-c-ccccc-d-ddddd"
print re.findall("[^-]+-[^-]+", s)

Выход:

['aaaa-aa', 'bbbb-bb', 'c-ccccc', 'd-ddddd']

Обновление для Ника D:

n = 3
print re.findall("-".join(["[^-]+"] * n), s)

Выход:

['aaaa-aa-bbbb', 'bb-c-ccccc']
1 голос
/ 25 октября 2009

РЕДАКТИРОВАТЬ: Исходный код, который я разместил, не работал. Эта версия делает:

Я не думаю, что вы можете разделить все остальные, но вы можете разделить все - и присоединиться к каждой паре.

chunks = []
content = "this-is-a-string"
split_string = content.split('-')

for i in range(0, len(split_string) - 1,2) :
    if i < len(split_string) - 1:
        chunks.append("-".join([split_string[i], split_string[i+1]]))
    else:
        chunks.append(split_string[i])
0 голосов
/ 25 октября 2009

Я думаю, что некоторые из уже приведенных решений достаточно хороши, но для интереса я сделал эту версию:

def twosplit(s,sep):
  first=s.find(sep)
  if first>=0:
    second=s.find(sep,first+1)
      if second>=0:
        return [s[0:second]] + twosplit(s[second+1:],sep)
      else:
        return [s]
    else:
      return [s]
  print twosplit("this-is-a-string","-")
0 голосов
/ 25 октября 2009
l = 'this-is-a-string'.split()
nl = []
ss = ""
c = 0
for s in l:
   c += 1
   if c%2 == 0:
       ss = s
   else:
       ss = "%s-%s"%(ss,s)
       nl.insert(ss)

print nl
...