Python – удалить любой элемент из списка строк, который является подстрокой другого элемента

Итак, начиная со списка строк, как показано ниже

string_list = ['rest', 'resting', 'look', 'look', 'it', 'spit']

Я хочу удалить любой элемент из списка, который является подстрокой другого элемента, давая результат, например …

string_list = ['resting', 'look', 'spit']

У меня есть код, который это делает, но он смущающе уродлив и, вероятно, бесполезен. Есть ли простой способ сделать это в Python?

  • Как получить «USDJPY» (курсы валют) с помощью pandas и yahoo finance?
  • Как получить (и использовать) расширенные разрешения в Facebook с помощью Python / Django
  • Невозможно установить lxml на windows, фатальная ошибка C1083: Не удается открыть файл include: 'libxml / xmlversion.h'
  • закрытие python с назначением внешней переменной внутри внутренней функции
  • Twisted spawnProcess, отправить вывод одного процесса для ввода другого
  • Как указать порядок установки для питона python?
  • Проверить список слов в другой строке
  • Чтение файла CSV с использованием Python
  • 7 Solutions collect form web for “Python – удалить любой элемент из списка строк, который является подстрокой другого элемента”

    Первый строительный блок: подстрока.

    Вы можете использовать для проверки:

     >>> 'rest' in 'resting' True >>> 'sing' in 'resting' False 

    Затем мы собираемся выбрать наивный метод создания нового списка. Мы добавим элементы по одному в новый список, проверяя, являются ли они подстрокой или нет.

     def substringSieve(string_list): out = [] for s in string_list: if not any([s in r for r in string_list if s != r]): out.append(s) return out 

    Вы можете ускорить его, сортируя, чтобы уменьшить количество сравнений (в конце концов, более длинная строка никогда не может быть подстрокой строки более короткой / равной длины):

     def substringSieve(string_list): string_list.sort(key=lambda s: len(s), reverse=True) out = [] for s in string_list: if not any([s in o for o in out]): out.append(s) return out 

    Вот возможное решение:

     string_list = ['rest', 'resting', 'look', 'looked', 'it', 'spit'] def string_set(string_list): return set(i for i in string_list if not any(i in s for s in string_list if i != s)) print(string_set(string_list)) 

    распечатывает:

     set(['looked', 'resting', 'spit']) 

    Примечание. Я создаю набор (используя выражение генератора), чтобы удалить, возможно, дублированные слова, поскольку кажется, что порядок не имеет значения.

    Еще один лайнер:

     [string for string in string_list if len(filter(lambda x: string in x,string_list)) == 1] 

    должен быть достаточно читабельным, а не пифоническим.

    Вот один из способов:

     def find_unique(original): output = [] for a in original: for b in original: if a == b: continue # So we don't compare a string against itself elif a in b: break else: output.append(a) # Executed only if "break" is never hit return output if __name__ == '__main__': original = ['rest', 'resting', 'look', 'looked', 'it', 'split'] print find_unique(original) 

    Он использует тот факт, что мы можем легко проверить, является ли одна строка подстрокой другого, используя оператор in . Он по существу проходит через каждую строку, проверяет, является ли она подстрокой другого, и добавляет себя в выходной список, если это не так.

    Это печатает ['resting', 'looked', 'split']

    Вот один лайнер, который делает то, что вы хотите:

     filter(lambda x: [x for i in string_list if x in i and x != i] == [], string_list) 

    Пример:

     >>> string_list = ['rest', 'resting', 'look', 'looked', 'it', 'spit'] >>> filter(lambda x: [x for i in string_list if x in i and x != i] == [], string_list) ['resting', 'looked', 'spit'] 

    Вот не оптимальный способ, используйте только в том случае, если списки невелики:

     for str1 in string_list: for str2 in string_list: if str1 in str2: string_list.remove(str1) 

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

     string_list = ['rest', 'resting', 'look', 'looked', 'it', 'spit'] for item in string_list: for item1 in string_list: if item in item1 and item!= item1: string_list.remove(item) print string_list 

    Вывод:

     >>>['resting', 'looked', 'spit'] 

    Надеюсь, поможет !

    Python - лучший язык программирования в мире.