У меня есть такой список:
list1 = [
'some',
'thing',
'is',
'here',
'dont',
'care',
'them',
'The process completed',
'process id: p1',
'process id: p2',
'Regards',
'some',
'thing',
'is',
'here',
'dont',
'care',
'them',
'The process completed',
'process id: p12',
'Regards',
]
Я собираюсь создать такой новый список (ожидаемый результат):
list3 = [
'The process completed:\nprocess id: p1, process id: p2',
'The process completed:\nprocess id: p12'
]
Я найду и сохраню от The process completed
до Regards
(но сам Regards
не учитывается).
Я попробовал это:
new_list = []
new_str = ''
for l in list1:
if l == 'The process completed':
new_str += l
new_str += l
if l == 'Regards':
new_list.append(new_str)
new_str = ''
pass
Я знаю, что это неправильно, но я подумал вот такую логику:
if `l == The process completed`, then save from that string up to `Regards`, but not `Regards` itself.
Then find another `The process completed` and do the same.
Как я могу это сделать?
Использование итераторов:
list3 = []
it = iter(list1)
while 'The process completed' in it:
list3.append('The process completed:\n' + ', '.join(iter(it.__next__, 'Regards')))
Я не знаю, как вы получили свои 3979 баллов, но вот код:
new_list = []
new_str = ''
for l in list1:
if l == 'The process completed':
new_str = l + ':\n'
elif l == 'Regards':
new_list.append(new_str)
new_str = ''
elif new_str != "":
new_str += l + ", "
Я верю, что вы справитесь с завершающей запятой.
Эти моменты могут относиться к разным темам, языкам и т. д. ОП может быть экспертом по базам данных.
Я «решил» проблему с конечной запятой, используя «ведущие запятые». Я опубликую «ответ» ниже...
Эти моменты пришли из того времени, когда я был молод и имел способность думать и решать проблемы. У кого-то есть такая способность:(
Этого можно добиться, перебирая список и определяя сегменты, которые начинаются с «Процесс завершен» и заканчиваются перед «С уважением». Соответствующие строки в этих сегментах затем можно накапливать и форматировать по желанию.
list1 = [
'some', 'thing', 'is', 'here', 'dont', 'care', 'them',
'The process completed', 'process id: p1', 'process id: p2', 'Regards',
'some', 'thing', 'is', 'here', 'dont', 'care', 'them',
'The process completed', 'process id: p12', 'Regards',
]
list3 = []
new_str = ''
collecting = False
for l in list1:
if l == 'The process completed':
collecting = True
new_str = l + ':\n'
elif l == 'Regards' and collecting:
list3.append(new_str.strip())
collecting = False
elif collecting:
new_str += l + ', ' if l.startswith('process id:') else ''
list3 = [s.rstrip(', ') for s in list3]
print(list3)
Объяснение:
сбор: этот флаг указывает, собираете ли вы в данный момент строки для сегмента.
new_str: эта строка накапливает данные сегмента между «Процесс завершен» и «С уважением».
Условные обозначения:
Когда вы видите сообщение «Процесс завершен», вы начинаете собирать и инициализировать new_str.
Вы прекращаете сбор, когда нажимаете «С уважением» и сохраняете накопленные данные.
При сборе соответствующие строки, начинающиеся с «идентификатора процесса:», добавляются в new_str с правильным форматированием.
Я думаю, это поможет тебе
Предполагая, что у каждого 'The process completed'
есть закрытие 'Regards'
, вы можете найти индексы и разрезать список.
indices = [i for i, x in enumerate(list1) if x in {'The process completed', 'Regards'}]
list3 = [f'{list1[indices[i]]}:\n{", ".join(list1[indices[i]+1:indices[i+1]])}' for i in range(0, len(indices), 2)]
print(list3)
Выход
['The process completed:\nprocess id: p1, process id: p2',
'The process completed:\nprocess id: p12']
Также предполагается, что в другом месте нет дополнительных 'Regards'
.
На самом деле это не отвечает на ваш прямой вопрос о разрыве цикла, но решает требования высокого уровня.
Я собираюсь найти и сохранить от «Процесс завершен» до «С уважением» [исключая «С уважением»]
list1 = [
'some',
'thing',
'is',
'here',
'dont',
'care',
'them',
'The process completed',
'process id: p1',
'process id: p2',
'Regards',
'some',
'thing',
'is',
'here',
'dont',
'care',
'them',
'The process completed',
'process id: p12',
'Regards',
]
e = 0
done = False
list3 = []
while not done:
try:
s = list1.index("The process completed", e)
e = list1.index("Regards", s)
ent = list1[s] + ":\n" + ', '.join(list1[s+1:e])
list3.append(ent)
except ValueError as e:
done = True
print(list3)
Выход
['The process completed:\nprocess id: p1, process id: p2', 'The process completed:\nprocess id: p12']
В других постах было следующее:
Объяснение:
index() принимает начальную позицию (s, e). Найдите начальный тег, начинающийся с предыдущего конечного тега (e), отмеченного цифрой 0. Затем найдите конечный тег, начинающийся с текущего начального тега (ов). Разрежьте и соедините нужные части, добавьте в список3.
Используйте тестирование исключений index(), чтобы завершить цикл.
Я бы использовал while True:
и break
.
Я не видел решения @guy...
@nocomment - да, я думаю, это мой менталитет в области программирования потоков...
inchman1900 опубликовал решение, которое заканчивалось словами «обработать конечную запятую». Я обхожу это, используя «ведущую запятую».
new_list = []
new_str = ''
for l in list1:
if l == 'The process completed':
new_str = l + ':\n'
comma = '' ### What to use for a comma
elif l == 'Regards':
new_list.append(new_str)
new_str = ''
elif new_str != "":
new_str += comma + l ### Prefix with a "comma"
comma = ', ' ### Next time, we'll need a comma
По сути, вы ставите «запятую» перед новыми записями, но в первый раз «запятая» представляет собой пустую строку.
Очевидная проблема — установка константы «запятая» на каждой итерации, однако я обнаружил, что многие языки оптимизируют такое присвоение. Я не знаю, что делает Python, но если бы это был C, это могла бы быть всего лишь ОДНА машинная инструкция. Сравните это простое присваивание за цикл с работой, необходимой для поиска конца строки, проверки ее на наличие запятой, а затем удаления ее - я думаю, что накладные расходы на постоянное присваивание намного меньше.
Лучше, чем обрабатывать конечную запятую, вообще не создавать ее.