#python #string
Вопрос:
Приведены данные, аналогичные следующим:
['blah_12_1_bbc_services_cbbc', 'blah_12_1_high-profile_and_a', 'blah_12_1_iplayer,_known', 'blah_12_1_sport,_as_co-branded', 'er_ds_such_it', 'er_ds_websites_bbc_video', 'er_ds_bbc', 'er_ds_service._sport,', 'th_ss_13_a', "th_ss_13_iplayer,_large_bbc's", 'th_ss_13_the_a_co-branded', "th_ss_13_the_bbc's_bbc's"]
Я хотел бы создать список в виде:
['blah_12_1_', 'blah_12_1_', 'blah_12_1_', 'blah_12_1_', 'er_ds_', 'er_ds_', 'er_ds_', 'er_ds_', 'th_ss_13_', 'th_ss_13_', 'th_ss_13_', 'th_ss_13_']
Учитывая, что извлекаемые подстроки имеют разную длину и структуру, я не уверен, как это сделать.
Комментарии:
1. Не похоже, что здесь есть какая-то закономерность. Если нет никакой закономерности, то ваша проблема попадает в область вычислительного интеллекта. Если есть какой-либо определенный шаблон, например, часть строки перед определенным символом или знаком препинания, то это довольно просто.
2. Ну, вы могли бы определить проблему как получение самого длинного общего префикса в каждой группе, но у вас должно быть какое-то правило о том, когда строка достаточно отличается от предыдущей, чтобы начать новую группу-и это правило должно быть определено в вопросе, а не оставлено для людей, чтобы они могли догадаться в своих ответах.
3. Сначала выберите строки как случайные, а затем нажмите и отметьте задачу как завершенную. Кто-нибудь обязательно пожалуется и подскажет вам правильную схему.
4. Второй список в вашем примере не содержит уникальных подстрок. Вы можете разделить свои строки регулярным выражением, если они всегда имеют префикс с двумя символами подчеркивания, а затем взять вторую часть, которая кажется уникальной в вашем примере: «bbc_services_cbbc» и так далее.
5. @IgorZ извините — второй список-это идентификаторы, которые были извлечены из первого, я думаю, что это может быть невозможно программно, хотя это просто требует некоторой человеческой маркировки и т. Д
Ответ №1:
Вы можете использовать рекурсию:
from collections import defaultdict def paths(p, s = '', c = None): d = defaultdict(list) for a, *b in p: d[a].extend(b if not b else [b]) if c is None or len(d) == 1: yield from [j for a, b in d.items() for j in paths(b, s=s a '_', c=c if c is not None else len(b))] else: yield from [s]*c data = ['blah_12_1_bbc_services_cbbc', 'blah_12_1_high-profile_and_a', 'blah_12_1_iplayer,_known', 'blah_12_1_sport,_as_co-branded', 'er_ds_such_it', 'er_ds_websites_bbc_video', 'er_ds_bbc', 'er_ds_service._sport,', 'th_ss_13_a', "th_ss_13_iplayer,_large_bbc's", 'th_ss_13_the_a_co-branded', "th_ss_13_the_bbc's_bbc's"] r = list(paths([i.split('_') for i in data]))
Выход:
['blah_12_1_', 'blah_12_1_', 'blah_12_1_', 'blah_12_1_', 'er_ds_', 'er_ds_', 'er_ds_', 'er_ds_', 'th_ss_13_', 'th_ss_13_', 'th_ss_13_', 'th_ss_13_']
Ответ №2:
Это должно соответствовать вашим требованиям.
# Imports import os import numpy as np list_str = ['blah_12_1_bbc_services_cbbc', 'blah_12_1_high-profile_and_a', 'blah_12_1_iplayer,_known', 'blah_12_1_sport,_as_co-branded', 'er_ds_such_it', 'er_ds_websites_bbc_video', 'er_ds_bbc', 'er_ds_service._sport,', 'th_ss_13_a', "th_ss_13_iplayer,_large_bbc's", 'th_ss_13_the_a_co-branded', "th_ss_13_the_bbc's_bbc's"] def get_common_substring(list_str): # List sorted list_sorted = list(np.sort(list_str)) # Necessary to check if the new common string already exists in a more contracted form # (i.e for ["th_ss_13_iplayer,_large_bbc's", 'th_ss_13_the_a_co-branded', "th_ss_13_the_bbc's_bbc's"] # we want "th_ss_13_" not "th_ss_13_the" ) last_common_substring = None # Association between items and common substrings common_substrings = {} # result as a list as expected results = [] for i in range(len(list_sorted) - 1): # Iteration two by two items pair_items = list_sorted[i:i 2] # Search for common substring common_substring = os.path.commonprefix(pair_items) if len(common_substring) gt; 0: if last_common_substring is not None and last_common_substring in common_substring: # Necessary to check if the new common string already exists in a more contracted form common_substring = last_common_substring # We add the association for the pair of items common_substrings[pair_items[0]] = common_substring common_substrings[pair_items[1]] = common_substring # We keep trace of the last common substring last_common_substring = common_substring else: if pair_items[0] not in common_substrings: # This is the case when there are no common substrings common_substrings[pair_items[0]] = None # To have the result as a list as expected for item in common_substrings: results.append(common_substrings[item]) return results get_common_substring(list_str)