Всем привет. Есть функция внутри программы, которая проверяет формат строки на предмет ненужных символов. Если выделить в отедльный скрипт
import string
spisok_star = list(...)
spisok_nov = []
simvoli = string.ascii_letters + string.digits + string.punctuation + string.whitespace
for ludi in spisok:
for b in ludi:
if b in simvoli:
spisok_nov.append(ludi)
Список этот содержит элементы вида «Имя Фамилия Дата Рождения» (из файла выдернуто). Трабла в том, что таким образом все прошедшие проверку на символы элементы списка в новом списке повторяются столько раз, сколько символов в элементе. Это из за итерации при проверки на вхождение. Так каким образом это можно исправить, чтобы изначально запись в новый список производилась 1 раз? Не форматируя список лишний раз всякими множествами и т.д.
Еще раз, ребят. Я знаю, что это все можно сделать отдельно, вне этих циклов, но тогда и код деоптимизируется. Придется лишний раз хранить список, который будет переформировываться и брать ресурсы. Если не найду вариантов, я конечно так и сделаю, но если есть типс'энд'трикс для этого, рад буду узнать.
Потому и обратился, что не могу сообразить. А оптимизация нужна, потому что списки, с которыми работаю, по несколько миллионов строк. И функция далеко не единственная в программе. Чем быстрее работает, тем лучше.
def verify(name):
for c in name:
if c not in simvoli:
return False
return True
for ludi in spisok:
verified = True
for name in ludi:
verified &= verify(name)
if verified:
spisok_nov.append(ludi)
Честно говоря, из исходного сообщения непонятно, что именно тебе надо получить, старайся яснее формулировать мысли, возможно не привязываясь к конкретной задаче.
Как я понял тебе надо выбрать из некоего списка строк элементы, которые содержат только разрешенные буквы. Набросаю псевдокод:
def is_valid_string(s):
"Возвращает True, если строка содержит только разрешённые буквы"
for x in s:
if x - недопустимая буква:
return False
return True
def copy_valid_items(lst):
r = []
for x in list:
if is_valid_string(x):
r.append(x)
return r
Это не идиоматический Python, а скорее указание на способ декомпозиции задачи.
оптимизация нужна, потому что списки, с которыми работаю, по несколько миллионов строк.
Сам я не питонист, а код уже предложили. Добавлю только, что сначала надо написать рабочий корректный код, пусть даже неэффективный, а потом уже его оптимизировать. Причём оптимизировать только тогда, когда он действительно работает неприемлемо медленно. А оптимизировать примерно так: выявляешь самые узкие места путём замеров времени и оптимизируешь только их, а не вообще что угодно. А там могут быть разные варианты:
1. Улучшение алгоритма — самое действенное.
2. Замена вызовов функций на вставки — менее действенно.
3. В крайнем случае написание узкого места на другом языке.
Да, это работает. И да, я могу так же решить вопрос. Как уже писал, мне было интересно, можно ли прямо в том лупе, который у меня описан, закидывать подходящие элементы в новый список. Я так же могу описать через удаление из копии списка. Понял ты правильно, и написал все верно, но вопрос таки был чуть-чуть в другом.
Это самое очевидное, что просится. Брейк, как уже писал, в лупе не позволит проверять все символы из элементов на вхождение в разрешенные. Так не выйдет. Наверное, вы все описали вариант с доп.функцией, сравню ее с закидыванием в сет после моего изначального варианта. Всем спасибо.
Сначала надо убедиться, что программа действительно работает неприемлемо медленно, а потом, если это так, отпрофилировать её ( вот статья на хабре о профилировании в питоне: https://habrahabr.ru/company/mailru/blog/202832/ ) и убедиться, что большую часть времени жрёт именно эта функция (а может другая жрёт ещё больше, тогда начинать оптимизацию надо с той другой). Ну и Begemoth посоветовал, если я правильно его понял, вместо прохода циклов попробовать регулярные выражения. А если он имел в виду не их, то я советую их попробовать. В питоне они должны быть и по идее могут оказаться быстрее циклов, т. к. реализованы на более низком уровне. Т. е. что-то вроде такого : «^[a-z]+$» проверяет строку на содержание только строчных латинских букв.