Удалить символы из конца каждого элемента в списке строк на основе другого списка строк (например, строки черного списка) - PullRequest
4 голосов
/ 15 октября 2019

У меня есть словарь, который содержит ряд уникальных строковых значений для ключа «sample». Я преобразовываю этот ключевой «образец» в список для построения графика, однако я хочу создать другой список с равным количеством элементов, которые разбивают определенные строки в конце каждого элемента, чтобы создать «чистый» список, который затем может группировать определенныеобразцы вместе для построения. Например, мой черный список выглядит так:

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']

с желаемым результатом новогоlist:

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

Для контекста я понимаю, что будут некоторые элементы, которые затем будут одинаковыми - я хочу использовать этот список для компиляции кадра данных вместе со списками с равным количеством сгенерированных значенийдругие ключи из этого словаря, которые будут использоваться в качестве идентификатора при построении (то есть, чтобы я мог использовать его для группировки / раскраски всех этих значений одинаково). Обратите внимание, что может быть различное количество символов подчеркивания, и в моем списке строк могут быть элементы, которые не содержат значений из черного списка (поэтому я не могу использовать какой-либо вариант разбиения, например, в последнем подчеркивании).

Это похоже на эту проблему: Как я могу удалить несколько символов в списке?

, но я не хочу, чтобы он был настолько обобщенным / жадным и в идеале был быЯ хотел бы удалить его только с конца, поскольку у пользователя может быть входной файл с частями этих строк (например, 1 в sample1_D) внутри. Мне не обязательно использовать черный список, если есть другое решение, просто кажется, что это может быть самый простой способ.

Ответы [ 4 ]

3 голосов
/ 15 октября 2019

Используйте 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']
1 голос
/ 15 октября 2019

Вы можете перебрать свой список образцов, если последний символ элемента является цифрой, то вы можете перебрать элементы черного списка, проверяя, заканчивается ли строка этим. Если это так, то вы можете удалить элемент черного списка из строки и переназначить результат в список образцов.

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']
1 голос
/ 15 октября 2019

Вы можете использовать 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']

Узнайте, почему это путь,если вам нужна скорость, здесь .

1 голос
/ 15 октября 2019

Итак, посмотрите, соответствует ли это вашим требованиям.

По сути, вы просто делитесь на символ '_' и проверяете, есть ли последнее разделение в списке в вашем черном списке. Если 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']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...