Эффективный способ в Python удалить элемент из строки, разделенной запятыми
Я ищу наиболее эффективный способ добавить элемент в строку, разделенную запятыми, сохраняя при этом алфавитный порядок слов:
Например:
string = 'Apples, Bananas, Grapes, Oranges'
subtraction = 'Bananas'
result = 'Apples, Grapes, Oranges'
Также, способ сделать это, но при сохранении идентификаторов:
string = '1:Apples, 4:Bananas, 6:Grapes, 23:Oranges'
subtraction = '4:Bananas'
result = '1:Apples, 6:Grapes, 23:Oranges'
Пример кода очень ценится. Огромное спасибо.
4 ответов:
В идеале, что-то вроде:
input_str = '1:Apples, 4:Bananas, 6:Grapes, 23:Oranges' removal_str = '4:Bananas' sep = ", " print sep.join(input_str.split(sep).remove(removal_str))Сработает. Но python не возвращает новый список из remove (), поэтому вы не можете сделать это все в одной строке, и вам нужны временные переменные и т. д. Аналогичное решение, которое действительно работает:
input_str = '1:Apples, 4:Bananas, 6:Grapes, 23:Oranges' removal_str = '4:Bananas' sep = ", " print sep.join([ i for i in input_str.split(sep) if i != removal_str ])Однако, чтобы быть максимально корректным, предполагая, что у вас нет гарантии, что все элементы действительны, вам нужно будет проверить, что каждый элемент соответствует всем данным вам спецификациям, а именно, что они имеют формат номер:идентификатор. Самый простой способ это делается для того, чтобы использовать модуль re для поиска определенного формата регулярного выражения, возврата всех результатов и пропуска результатов, которые не соответствуют тому, что вы хотите. Используя намеренно компактный код, вы получаете достаточно короткое решение, которое хорошо поддается проверке:
def str_to_dictlist(inp_str): import re regexp = r"(?P<id>[0-9]+):(?P<name>[a-zA-Z0-9_]+)" return [ x.groups() for x in re.finditer(regexp, inp_str) ] input_str = '1:Apples, 4:Bananas, 6:Grapes, 23:Oranges' subtraction_str = "4:Bananas" sep = ", " input_items = str_to_dictlist(input_str) removal_items = str_to_dictlist(subtraction_str) final_items = [ "%s:%s" % (x,y) for x,y in input_items if (x,y) not in removal_items ] print sep.join(final_items)Это также имеет преимущество обработки нескольких удалений одновременно. Поскольку входной формат и форматы удаления очень похожи, а входной формат имеет несколько элементов, имеет смысл, что формат удаления может потребоваться поддерживайте их тоже - или, по крайней мере, что полезно иметь такую поддержку.
Обратите внимание, что выполнение этого способа (использование re для поиска) затруднило бы обнаружение элементов, которые не проверяются; он просто сканировал бы все, что делает. В качестве взлома вы можете посчитать запятые во входных данных и сообщить предупреждение о том, что что-то не удалось разобрать:
if items_found < (num_commas + 1): print warning_strЭто также предупредит о запятых без пробелов.
Чтобы правильно разобрать более сложные входные строки, необходимо разбейте его на отдельные маркеры, отслеживайте входные строки и столбцы по мере анализа, печатайте ошибки для чего-либо неожиданного и, возможно, даже обрабатывайте такие вещи, как отслеживание и построение графиков для более сложных входных данных, таких как исходный код. Для этого загляните в модуль pyparsing (который является сторонней загрузкой; он не поставляется с python).
Комментарий Мэтью выше-правильный подход, но если вы уверены, что
,(запятая, за которой следует пробел) встречаются только как разделители, то что-то вроде этого будет работатьdef remove(str, element): items = str.split(", ") items.remove(element) return ", ".join(items)Я бы не рекомендовал использовать строки в качестве списков. Они предназначены для другой цели, и следовать совету Мэтью-это правильно.
>>> import re >>> re.sub("Bananas, |, Bananas$", "", "Apples, Bananas, Grapes, Oranges") 'Apples, Grapes, Oranges'Или
import re strng = '1:Apples, 4:Bananas, 6:Grapes, 23:Oranges' subtraction = '4:Bananas' result = re.sub(subtraction + ", |, " + subtraction, "", strng) print resultЭто работает на ваших примерах, но потребуется изменить, если строки вычитания могут содержать метасимволы регулярных выражений, такие как
[].*?{}\.Это, как заметил один комментатор, низкоуровневая строковая операция. Это может просто работать, но подход, который учитывает структуру ваших данных, должен быть более надежным. Достаточно ли разбиения на запятую / пробел, или вам нужна надежность модуля
csv, зависит от возможных входных данных струны, которые ты ждешь.
Comments