Более краткий способ удалить несколько элементов из списка?

#python #string #list #split #strip

Вопрос:

Я пытаюсь разрезать и оборвать веревку. Я написал следующий код:

 my_list = ['from ab1c_table in WXYnprevious in time',
        'from abc3_table in MNOnprevious in time',
        'from ab1_cow_table in DZMC1_IN tabncurrent in time',
        'from abc4_table in ERDUncurrent in time']
my_list_1 = []
for j in my_list:
  s = j.split(" ")
  s.remove('from')
  s.remove('in')
  s.remove('in')
  s.remove('time')

  for k in s:
    k = k.replace('current', '')
    k = k.replace('previous', '')
    k = k.replace('n', '')
  my_list_1.append(k)
  if 'tab' in my_list_1:
    my_list_1.remove('tab')

print(my_list_1)
 

Это работает нормально, но проблема в том, что я должен удалить каждое слово отдельно. Есть ли способ сделать это в меньшем количестве строк?
Результат, который я ищу, это:

 ['WXY', 'MNO']
 

ПРАВКА 1 —

Как мне получить этот вывод —

 ['ab1c_table', 'WXY', 'abc3_table', 'MNO', 'ab1_cow_table', 'DZMC1_IN', 'abc4_table', 'ERDU']
 

Комментарии:

1. Вы можете создать список слов, которые вам нужно удалить, и повторить его.

2. Если шаблон всегда «от x в y», возможно, было бы разумнее разделить каждый элемент на пробелы, тогда целевой элемент всегда будет 4-м в списке.

3. Я думаю, что вы, вероятно, имели в виду «разделить» строку.

Ответ №1:

Я не уверен, что это то, что вы имеете в виду, но обычно регулярные выражения полезны для извлечения шаблонов из строк. Например:

 import re
my_list = ['from ab1c_table in WXYnprevious in time', 
           'from abc3_table in MNOnprevious in time']

my_list1 = [re.findall(r" ([A-Z]{3})n", s, )[0] for s in my_list]
print(my_list_1)
 

Редактировать:

Вот модификация шаблона регулярных выражений, отражающая дополнительные образцы строк, предоставленные OP в комментарии ниже:

 mylist = ['from ab1c_table in WXYnprevious in time', 
          'from abc3_table in MNOnprevious in time', 
          'from ab1_cow_table in DZMC1_IN tabncurrent in time', 
          'from abc4_table in ERDUncurrent in time']

my_list1 = [re.findall(r"_table in (S )(?:| tab)n.* in time", s)[0] for s in mylist]

print(my_list1)
 

Это дает:

 ['WXY', 'MNO', 'DZMC1_IN', 'ERDU']
 

Изменить 2:

_table Шаблоны захвата версий:

 import re
from itertools import chain

mylist = ['from ab1c_table in WXYnprevious in time', 
          'from abc3_table in MNOnprevious in time', 
          'from ab1_cow_table in DZMC1_IN tabncurrent in time', 
          'from abc4_table in ERDUncurrent in time']

my_list1 = list(chain(*[re.findall(r"from (S _table) in (S ).*?n.* in time", s)[0] for s in mylist]))

print(my_list1)
 

Это дает:

 ['ab1c_table', 'WXY', 'abc3_table', 'MNO', 'ab1_cow_table', 'DZMC1_IN', 'abc4_table', 'ERDU']
 

Комментарии:

1. Это было бы проблемой для «из ABC1_table» или XYZ, не являющегося ascii в верхнем регистре.

2. @tdelaney Это зависит от того, каким должен быть результат — последовательности из трех заглавных букв, трех заглавных букв, за которыми следует новая строка? Я не уверен.

3. Я тоже не уверен. Мы недостаточно знаем об этих строках, чтобы действительно сказать. Давайте посмотрим, сможет ли ОП уточнить.

4. Это может граничить с проблемой XY.

5. @tdelaney В исходном коде операции «вкладка» удаляется, поэтому, я думаю, она не должна совпадать.

Ответ №2:

Вы можете написать шаблон , который соответствует строкам и соответствует, например, предыдущему или текущему использованию (?:previous|current) , и захватить последнюю часть первой строки в группе 1.

Сначала проверьте, есть ли совпадение, и если есть, установите новое значение в значение группы 1.

Если совпадения нет, оставьте значение неизмененным.

 bfrom w  in (w )nprevious in timeb
 

Смотрите значение группы захвата зеленым цветом в этой демонстрации регулярных выражений.

 import re

pattern = r"bfrom w  in (w )n(?:previous|current) in timeb"
my_list = ['from ab1c_table in WXYnprevious in time', 'from abc3_table in MNOnprevious in time']

for n, i in enumerate(my_list):
    m = re.match(pattern, i)
    if m:
        my_list[n] = m.group(1)

print(my_list)
 

Выход

 ['WXY', 'MNO']
 

Ответ №3:

Как я уже предлагал ранее, я думаю, что это можно сделать намного проще с помощью простого split() . Строки всегда следуют одному и тому же шаблону. Все, что вам нужно сделать, это разделить пробелы и удалить второй и четвертый элемент из результирующих списков.

 elems = list()
for e in my_list:
    # e.g., the first element becomes
    # ['from', 'ab1c_table', 'in', 'WXY', 'previous', 'in', 'time']
    parts = e.split()
    elems.extend([parts[1], parts[3]])

print(elems)
 

Результат:

 ['ab1c_table',
 'WXY',
 'abc3_table',
 'MNO',
 'ab1_cow_table',
 'DZMC1_IN',
 'abc4_table',
 'ERDU']
 

Ответ №4:

Из вопроса неясно, что является переменной в строках, но, похоже, это регулярное выражение подойдет. Цель состоит в том, чтобы сопоставить все статичное с некоторыми подстановочными знаками и группами захвата в скобках для данных, которые вы хотите получить в результате. Поскольку вам нужны две части данных в том порядке, в котором они находятся в строке, вы можете создать две группы захвата и расширить список результатов.

 import re
  
my_list = ['from ab1c_table in WXYnprevious in time',
        'from abc3_table in MNOnprevious in time',
        'from ab1_cow_table in DZMC1_IN tabncurrent in time',
        'from abc4_table in ERDUncurrent in time']

result = []
for value in my_list:
    result.extend(re.match(r"from (. _table) in (S )", value).groups())
print(result)
 

Результат

 ['ab1c_table', 'WXY', 'abc3_table', 'MNO', 'ab1_cow_table', 'DZMC1_IN', 'abc4_table', 'ERDU']
 

Комментарии:

1. Это работает для этого вывода, если мне нужен немного другой вывод, как его получить? Я отредактировал вопрос

2. Обновлено для получения новых данных