#python #string #list
#python #строка #Список
Вопрос:
Проблема со слегка измененными строками в списке при проверке по отсортированному списку строк.
Я проверяю строки, представляющие содержимое из некоторых файлов. И у меня есть список определенных строк, которые я проверяю, однако иногда в конце одной и той же строки может быть добавлена звездочка (*), что приводит к слегка измененным дубликатам в этом списке.
В настоящее время:
# This is minimal very minimal code example:
for _word in sorted(['Microsoft','Microsoft*']):
print(_word)
Желаемый:
for _word in sorted(['Microsoft']):
print(_word)
# But still be able to check for 'Microsoft*' without having duplicates in the list.
Окончательное решение:
import os
import sys
if __name__ == '__main__':
default_strings = sorted([
'microsoft',
'linux',
'unix',
'android'
])
text = str("""
Microsoft* is cool, but Linux is better.
""")
tokens = text.split(" ")
for token in tokens:
token = token.lower()
if token.endswith('*'):
token = token[:-1]
if token in default_strings:
print(token)
РЕДАКТИРОВАТЬ: Если есть способ получше, пожалуйста, дайте мне знать. Большое спасибо всем, кто участвовал и откликнулся.
Комментарии:
1. фильтруйте специальные символы и используйте set вместо list.
2. Нет, наборы здесь не работают. Я протестировал sets() и {} dictionary.
3. да, но можете ли вы сначала отфильтровать специальные символы, а затем преобразовать их в set?
4. Просто определите свой собственный,
MySet
расширив встроенныйset
класс, а затем измените метод двойного подчеркивания, где проверка дублирования будет игнорировать специальные символы, такие как звездочка (*). Наконец, приведите свой список к типу MySet.
Ответ №1:
Основываясь на моем комментарии; Если вы не хотите использовать set, тогда,
my_filters = ['*']
my_list = ['Microsoft','Microsoft*']
final_list = [ x.replace(y,'') for x in my_list for y in my_filters if y in x ]
Но я бы сказал, что сначала отфильтруйте специальные символы в вашем списке ввода и просто преобразуйте (приведите) их в set.
Комментарии:
1. @JohnSmith в каком смысле это неэффективно? Предложенное вами решение столь же эффективно, за исключением того, что ваше
default_strings
должно бытьset
, иначе оба этих подхода будут квадратичными по времени. Редактировать: и зачем их сортировать?2. @JohnSmith преобразование в
set
— это единовременная предварительная стоимость. Но если вы собираетесь проверять членство много раз , то набор определенно более эффективен . Кроме того, поиск по отсортированному списку выполняется быстрее, только если вы используете двоичный поиск , но вы этого не делаете. Просто используй set, чувак, это именно то, для чего они предназначены . Кроме того, если вы можете «вручную определить» свой список, вы можете просто сделать это с помощью set . Не учитывайте время создания в своих таймингах. Опять же,set
объекты устраняют дубликаты, но это не их цель, их назначение — быстрое тестирование членства3. @JohnSmith gist.github.com/juanarrivillaga / … просто посмотрите на тайминги. Да, загрузка набора изначально будет стоить дороже , но если вы собираетесь использовать набор для тестирования членства, тогда это будет намного быстрее . Я не думаю, что вы понимаете разницу между этими структурами данных, это основной вариант использования set . Кроме того, любые накладные расходы на создание набора будут сведены к минимуму, если вы затем будете сортировать список. Обратите внимание, проверка membershipt в наборе постоянно длится около 25 наносекунд, не имеет значения, содержит ли он один элемент или 1000 элементов.
4. @JohnSmith с другой стороны, к тому времени, когда вы проверяете элемент в списке из 1000 элементов, это занимает 12 микросекунд, что примерно в 500 раз быстрее с набором . И прелесть в том, что вы будете продолжать замедляться по мере увеличения списка, но он будет оставаться неизменным независимо от размера набора
5. @JohnSmith да,
set
объекты существуют для проверки членства . Это их основная цель существования. Если вам нужно выполнить итерацию по чему-либо,list
будет самой быстрой встроенной структурой данных python для этого.