【问题标题】:Remove characters from the end of each element in a list of strings based on another list of strings (e.g. blacklist strings)根据另一个字符串列表(例如黑名单字符串)从字符串列表中每个元素的末尾删除字符
【发布时间】:2019-10-14 21:00:00
【问题描述】:

我有一个字典,其中包含键“样本”的许多唯一字符串值。我正在将此键“样本”转换为用于绘图的列表,但是我想生成另一个具有相同数量元素的列表,这些元素在每个元素的末尾去除某些字符串以生成一个“干净”列表,然后可以对某些元素进行分组样品一起作图。例如,我的黑名单如下所示:

blacklist = ['_001', '_002', '_003', '_004', '_005', '_006', '_007', '_008', '_009', \
                       '_01', '_02', '_03', '_04', '_05', '_06', '_07', '_08', '_09', \
                       '_1', '_2', '_3', '_4', '_5', '_6', '_7', '_8', '_9']

我想从我的字典生成的示例列表中的每个项目中删除:

sample = [(d['sample']) for d in my_stats]
sample
['sample_A', 'sample_A_001', 'sample_A_002', 'my_long_sample_B_1', 'other_sample_C_08', 'sample_A_03', 'sample1_D_07']

具有新列表的所需结果:

sample
['sample_A', 'sample_A', 'sample_A', 'my_long_sample_B', 'other_sample_C', 'sample_A', 'sample1_D']

对于上下文,我知道会有一些元素是相同的——我想使用这个列表来编译一个数据框,并结合具有相同数量值的列表从这个字典生成其他键,这些键将是用作绘图中的 id(即,我可以使用它对所有这些值进行相同的分组/着色)。请注意,可能有不同数量的下划线,并且我的字符串列表中可能有一些元素不包含黑名单中的任何值(这就是为什么我不能在最后一个下划线上使用某些拆分变体的原因)。

这与此问题类似: How can I remove multiple characters in a list?

但我不希望它如此笼统/贪婪,并且理想情况下只希望从末尾删除它,因为用户可能在内部有一个包含这些字符串部分的输入文件(例如 sample1_D 中的 1)。如果有其他解决方案,我不一定需要使用黑名单,这似乎是最简单的方法。

【问题讨论】:

  • 正则表达式pattern$
  • 到目前为止你尝试了什么

标签: python regex python-3.x


【解决方案1】:

使用regex

import re

pattern = '|'.join(blacklist)
[re.sub(pattern+'$', '', x) for x in sample]

输出

['sample_A',
 'sample_A',
 'sample_A',
 'my_long_sample_B',
 'other_sample_C',
 'sample_A',
 'sample1_D']

【讨论】:

  • 优秀。我不记得如何使用不需要的值列表进行正则表达式。感谢您的复习!
  • 请考虑 upvotingaccepting 解决方案。
  • @S3DEV 谢谢!我之前没有意识到这一点。更新了我之前的评论。
  • 这太好了,谢谢!抱歉,一天的工作结束了——直到今天早上才有机会查看。
【解决方案2】:

给你,看看这是否符合你的要求。

基本上,您只是在'_' 字符上进行拆分并测试列表中的最后一个拆分是否在您的黑名单中。如果True,则放下它,如果False 将字符串重新组合在一起;并根据结果构建一个新列表。

blacklist = ['_001', '_002', '_003', '_004', '_005', '_006', '_007', '_008',
             '_01', '_02', '_03', '_04', '_05', '_06', '_07', '_08', '_09',
             '_1', '_2', '_3', '_4', '_5', '_6', '_7', '_8', '_9']
sample = ['sample_A', 'sample_A_001', 'sample_A_002', 'my_long_sample_B_1',
          'other_sample_C_08', 'sample_A_03', 'sample1_D_07']
results = []

for i in sample:
    splt = i.split('_')
    value = '_'.join(splt[:-1]) if '_{}'.format(splt[-1:][0]) in blacklist else '_'.join(splt)
    results.append(value)

print(results)

输出:

['sample_A', 'sample_A', 'sample_A', 'my_long_sample_B', 'other_sample_C', 'sample_A', 'sample1_D']

【讨论】:

  • 这在特异性方面非常棒,只需从列表中每个字符串的末尾抓取它,谢谢!
  • 由于仅根据最后一个分隔符匹配/删除黑名单值的特殊性而被接受为解决方案
【解决方案3】:

您可以使用正则表达式中的sub

import re
from functools import partial

blacklist = ['_001', '_002', '_003', '_004', '_005', '_006', '_007', '_008', '_009',
             '_01', '_02', '_03', '_04', '_05', '_06', '_07', '_08', '_09',
             '_1', '_2', '_3', '_4', '_5', '_6', '_7', '_8', '_9']


def sub(match, bl=None):
    if match.group() in bl:
        return ""
    return match.group()


repl = partial(sub, bl=set(blacklist))

sample = ['sample_A', 'sample_A_001', 'sample_A_002', 'my_long_sample_B_1', 'other_sample_C_08', 'sample_A_03',
          'sample1_D_07']

print([re.sub("_[^_]+?$", repl, si) for si in sample])

输出

['sample_A', 'sample_A', 'sample_A', 'my_long_sample_B', 'other_sample_C', 'sample_A', 'sample1_D']

看看为什么这是要走的路,如果你想要速度,here

【讨论】:

    【解决方案4】:

    您可以遍历您的示例列表,如果元素的最后一个字符是数字,那么您可以遍历您的黑名单项目,检查字符串是否以该字符结尾。如果是,那么您可以从字符串中删除黑名单项并将结果重新分配给示例列表。

    blacklist = [
        '_001', '_002', '_003', '_004', '_005', '_006', '_007', '_008', '_009',
        '_01', '_02', '_03', '_04', '_05', '_06', '_07', '_08', '_09',
        '_1', '_2', '_3', '_4', '_5', '_6', '_7', '_8', '_9'
    ]
    
    sample = ['sample_A', 'sample_A_001', 'sample_A_002', 'my_long_sample_B_1', 'other_sample_C_08', 'sample_A_03', 'sample1_D_07']
    
    for index, item in enumerate(sample):
        #check if the last char is a digit, if its not then it cant be in our black list so no point checking
        if item[-1].isdigit():
            for black in blacklist:
                if item.endswith(black):
                    sample[index] = item.rstrip(black)
    
    print(sample)
    

    输出

    ['sample_A', 'sample_A', 'sample_A', 'my_long_sample_B', 'other_sample_C', 'sample_A', 'sample1_D']
    

    【讨论】:

      猜你喜欢
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多