Эффективный способ в 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'


Пример кода очень ценится. Огромное спасибо.

596   4  

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).

Split on ', ', Удалите элемент и соедините.

Комментарий Мэтью выше-правильный подход, но если вы уверены, что , (запятая, за которой следует пробел) встречаются только как разделители, то что-то вроде этого будет работать

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

    Ничего не найдено.