Как разделить список строк по символам в Python
У меня есть список строк, как это:
org_list = ['', '<dialog xyz', 'string', 'more string', 'even more string etc',
'<dialog xyz', 'string', 'more string', 'even more string etc']
Мне нужно разделить список на подсписки строк, разделив их точно на '<'
символ, так что каждый список строк начинается с 'dialog xyz'
, Образец вывода:
[['<dialog xyz', 'string', 'more string', 'even more string etc'], ['<dialog
xyz', 'string', 'more string', 'even more string etc']]
Я уже пытался понять список, но он не работает (возвращает то же самое org_list
):
divided_list = [s.split(',') for s in ','.join(org_list).split('<')]
Я знаю, что это возможно с itertools
(видел это в некоторых ответах), но я все еще новичок, не очень понимаю их и хотел бы решить это с тем, что я понимаю, если это возможно.
8 ответов
Сначала мы можем создать list
из indexes
ссылаясь на позиции в org_list
где строка в этой позиции начинается с '<'
,
Затем мы можем перебрать их в list-comp
принятие slices
между каждой парой indexes
,
Тем не менее, в конце мы заметили, что последний slice
должен идти до конца org_list
поэтому мы должны объединить list
содержащий индекс один за концом, чтобы захватить это.
Надеюсь, вы сможете увидеть, как это описание переходит в следующий код.
inds = [i for i, s in enumerate(org_list) if '<' in s] + [len(org_list)]
div_l = [org_list[inds[i]:inds[i+1]] for i in range(len(inds)-1)]
который дает желаемый результат:
[['<dialog xyz', 'string', 'more string', 'even more string etc'],
['<dialog xyz', 'string', 'more string', 'even more string etc']]
Как насчет чего-то простого:
org_list = ['', '<dialog xyz', 'string', 'more string', 'even more string etc', '<dialog xyz', 'string', 'more string', 'even more string etc']
split_lists = []
for s in org_list:
if s == '':
continue
if s.startswith('<') or len(split_lists) == 0:
split_lists.append([s])
continue
split_lists[-1].append(s)
print(split_lists)
Выход:
[['<dialog xyz', 'string', 'more string', 'even more string etc'], ['<dialog xyz', 'string', 'more string', 'even more string etc']]
org_list = ['', '<dialog xyz', 'ztring', 'more ztring', 'even more string etc', '<dialog xyz', 'string', 'more string', 'even more string etc']
orig = []
start = False
new = []
for item in org_list:
if item == '<dialog xyz' or item == org_list[-1]:
if len(new) > 1:
orig.append(new)
new = []
start = True
if start:
new.append(item)
print(orig)
Это дает мне вывод, который вы хотите.
Это должно работать:
split_lists = []
for s in org_list:
if s.startswith('<') or len(split_lists) == 0:
split_lists.append([])
split_lists[-1].append(s)
Вот результат для вашего ввода:
>>> split_lists
[[''], ['<dialog xyz', 'string', 'more string', 'even more string etc'], ['<dialog xyz', 'string', 'more string', 'even more string etc']]
Если вы хотите игнорировать все строки перед первой строкой, которая начинается с '<', как пустая строка, которая является первым элементом в вашем org_list
, затем используйте это:
split_lists = []
for s in org_list:
if s.startswith('<'):
split_lists.append([])
if len(split_lists) == 0:
continue
split_lists[-1].append(s)
Ты можешь использовать itertools.groupby
:
import itertools
import re
org_list = ['', '<dialog xyz', 'string', 'more string', 'even more string etc',
'<dialog xyz', 'string', 'more string', 'even more string etc']
new_list = [list(b) for a, b in itertools.groupby(filter(None, org_list), key=lambda x:bool(re.findall('^\<dialog', x)))]
final_list = [new_list[i]+new_list[i+1] for i in range(0, len(new_list), 2)]
Выход:
[['<dialog xyz', 'string', 'more string', 'even more string etc'], ['<dialog xyz', 'string', 'more string', 'even more string etc']]
Это может помочь
org_list = ['', '<dialog xyz', 'string', 'more string', 'even more string etc',
'<dialog xyz', 'string', 'more string', 'even more string etc']
result = [i.split("|") if i.startswith("<") else ("<"+i).split("|") for i in "|".join(filter(None, org_list)).split("|<")]
print result
Выход:
[['<dialog xyz', 'string', 'more string', 'even more string etc'], ['<dialog xyz', 'string', 'more string', 'even more string etc']]
Вы можете сделать что-то вроде этого:
org_list = ['', '<dialog xyz', 'string', 'more string', 'even more string etc',
'<dialog xyz', 'string', 'more string', 'even more string etc']
flag=True
sub_list=[]
final_list=[]
text='<dialog xyz'
for i in org_list:
if i.startswith(text):
flag=False
if sub_list:
sub_list.insert(0,text)
final_list.append(sub_list)
sub_list=[]
else:
if flag==False:
sub_list.append(i)
sub_list.insert(0,text)
final_list.append(sub_list)
print(final_list)
выход:
[['<dialog xyz', 'string', 'more string', 'even more string etc'], ['<dialog xyz', 'string', 'more string', 'even more string etc']]
Фотоконкурс. Кто сделает функцию более сложной и медленной? Проще говоря, это Python.
org_list = ['', '<dialog xyz', 'string', 'more string', 'even more string etc',
'<dialog xyz', 'string', '', 'even more string etc' , '<dialog xyz', 'string', 'more string',]
def slicelist (pred, iterable):
element = []
alw = False
for s in iterable:
sw = s.startswith
if sw(pred):
element.append([])
alw=True
if alw :
element[-1].append(s)
return element
print slicelist('<', org_list)
Если вы хотите сделать генератор (итератор), вам нужно изменить следующие операторы в приведенном выше примере: return
в yield
а также print slicelist('<', org_list)
в print list(slicelist('<', org_list))