从列表中删除多个元素的更简洁的方法?

More succinct way to remove multiple elements from a list?

我正在尝试对字符串进行切片和剥离。我写了下面的代码:

my_list = ['from ab1c_table in WXY\nprevious in time',
        'from abc3_table in MNO\nprevious in time',
        'from ab1_cow_table in DZMC1_IN tab\ncurrent in time',
        'from abc4_table in ERDU\ncurrent 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']

我不确定这是否是您的想法,但通常正则表达式对于从字符串中提取模式很有用。例如:

import re
my_list = ['from ab1c_table in WXY\nprevious in time', 
           'from abc3_table in MNO\nprevious 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 WXY\nprevious in time', 
          'from abc3_table in MNO\nprevious in time', 
          'from ab1_cow_table in DZMC1_IN tab\ncurrent in time', 
          'from abc4_table in ERDU\ncurrent 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 WXY\nprevious in time', 
          'from abc3_table in MNO\nprevious in time', 
          'from ab1_cow_table in DZMC1_IN tab\ncurrent in time', 
          'from abc4_table in ERDU\ncurrent 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']

从问题中不清楚什么是字符串中的变量,但似乎这个正则表达式就可以了。目标是将静态的所有内容与一些通配符和带括号的捕获组匹配,以获得结果中所需的数据。由于您希望按照在字符串中找到的顺序获取两条数据,因此您可以创建两个捕获组并扩展结果列表。

import re
  
my_list = ['from ab1c_table in WXY\nprevious in time',
        'from abc3_table in MNO\nprevious in time',
        'from ab1_cow_table in DZMC1_IN tab\ncurrent in time',
        'from abc4_table in ERDU\ncurrent 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']

正如我之前建议的那样,我认为使用简单的 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']

您可以使用 (?:previous|current) 编写一个匹配字符串的模式,例如之前或当前的匹配,并捕获第 1 组第一行的最后部分。

首先检查是否匹配,如果匹配则将新值设置为第1组值。

如果没有匹配项,则保留值不变。

\bfrom \w+ in (\w+)\nprevious in time\b

请参阅此 regex demo 中绿色的捕获组值。

import re

pattern = r"\bfrom \w+ in (\w+)\n(?:previous|current) in time\b"
my_list = ['from ab1c_table in WXY\nprevious in time', 'from abc3_table in MNO\nprevious 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']