#python #split #csv
#python #разделить #csv
Вопрос:
Я пытаюсь разделить строку, такую как приведенная ниже, со всеми разделителями ниже, но только один раз.
string = 'it; seems; liketa goodtday to watchvavmovie.'
delimiters = 't v ;'
В этом случае вывод будет:
['it', ' seems; like', 'a goodtday to watch', 'avmovie.']
Очевидно, что приведенный выше пример является бессмысленным примером, но я пытаюсь узнать, возможно ли это. Будет ли в порядке достаточно сложное регулярное выражение?
Извиняюсь, если этот вопрос был задан раньше. Я немного поискал и не смог найти что-то похожее на мой пример. Спасибо за ваше время!
Ответ №1:
Это должно сработать:
import re
def split_once_by(s, delims):
delims = set(delims)
parts = []
while delims:
delim_re = '({})'.format('|'.join(re.escape(d) for d in delims))
result = re.split(delim_re, s, maxsplit=1)
if len(result) == 3:
first, delim, s = result
parts.append(first)
delims.remove(delim)
else:
break
parts.append(s)
return parts
Пример:
>>> split_once_by('it; seems; liketa goodtday to watchvavmovie.', 'tv;')
['it', ' seems; like', 'a goodtday to watch', 'ax0bmovie.']
Ответ Burning Alcohol вдохновил меня на написание этой (IMO) лучшей функции:
def split_once_by(s, delims):
split_points = sorted((s.find(d), -len(d), d) for d in delims)
start = 0
for stop, _longest_first, d in split_points:
if stop < start: continue
yield s[start:stop]
start = stop len(d)
yield s[start:]
с использованием:
>>> list(split_once_by('it; seems; liketa goodtday to watchvavmovie.', 'tv;'))
['it', ' seems; like', 'a goodtday to watch', 'ax0bmovie.']
Комментарии:
1. Спасибо; это было полезно, и я ценю, что вы снова повторяете процесс, чтобы придумать другой ответ.
2. Поддержал этот ответ, поскольку он использует меньше памяти, но логика @orlp и моя должна быть одинаковой. Рад, что мой ответ может вдохновить на обсуждение!
Ответ №2:
Простой алгоритм будет делать,
test_string = r'it; seems; liketa goodtday to watchvavmovie.'
delimiters = [r't', r'v', ';']
# find the index of each first occurence and sort it
delimiters = sorted(delimiters, key=lambda delimiter: test_string.find(delimiter))
splitted_string = [test_string]
# perform split with option maxsplit
for index, delimiter in enumerate(delimiters):
if delimiter in splitted_string[-1]:
splitted_string = splitted_string[-1].split(delimiter, maxsplit=1)
splitted_string.pop(index)
print(splitted_string)
# ['it', ' seems; like', 'a good\tday to watch', 'a\vmovie.']
Ответ №3:
Просто создайте список шаблонов и примените их один раз:
string = 'it; seems; liketa goodtday to watchvavmovie.'
patterns = ['t', 'v', ';']
for pattern in patterns:
string = '*****'.join(string.split(pattern, maxsplit=1))
print(string.split('*****'))
Вывод:
['it', ' seems; like', 'a goodtday to watch', 'ax0bmovie.']
Итак, что это "*****"
??
На каждой итерации, когда вы применяете split
метод, вы получаете список. Итак, на следующей итерации вы не сможете применить .split ()
метод (потому что у вас есть список), поэтому вам нужно объединить каждое значение этого списка с каким-нибудь странным символом, например "****"
, или "@@@"
или "^^^^^^^"
или что угодно, чтобы повторно применить split () на следующей итерации. Наконец, для каждой "*****"
вашей строки у вас будет один шаблон списка, так что вы можете использовать это для окончательного разделения.
Комментарии:
1. Что, если входные данные содержат
*****
?2. на каждой итерации, когда вы применяете разделение, вы получаете список. Итак, на следующей итерации я не могу применить .split() (потому что у меня есть список), поэтому я присоединяюсь к этому списку с каким-то странным символом, таким как «****», чтобы повторно применить метод split()
3. Вы не ответили на мой вопрос. Что делать, если входная строка содержит
****
или что вы выберете как «что-то странное»?4. Я привел пример, чтобы прояснить свой ответ.
5. Я понимаю ваш ответ, мой вопрос является педагогическим, чтобы попытаться заставить вас осознать проблему с вашим ответом.