Подскажите, как можно упростить код?
Написал код к задаче, где нужно написать функцию, которая будет искать совпадения с заданным словарем, флаг функции letter_case отвечает за то, нужно ли сравнивать регистр символов или Python и python это одно и то же слово.
Но мне вообще не нравится, что для поднятого флага я продублировал такой же кусок кода, уверен что можно добавить логику, чтобы это вместить компактно, но я не могу до неё додуматься...
И хотел бы по возможности услышать замечания о коде: как я мог его упростить или выбрать легче решение, соответствует ли мой код общепринятым правилам названия переменных и PEP-8!
articles_dict = [
{
"title": "Endless ocean waters.",
"author": "Jhon Stark",
"year": 2019,
},
{
"title": "Oceans of other planets are full of silver",
"author": "Artur Clark",
"year": 2020,
},
{
"title": "An ocean that cannot be crossed.",
"author": "Silver Name",
"year": 2021,
},
{
"title": "The ocean that you love.",
"author": "Golden Gun",
"year": 2021,
},
]
def find_articles(text_filter, letter_case=False):
new_d = []
if letter_case:
for d in articles_dict:
for key_d, val in d.items():
if str(val).find(text_filter) != -1:
new_d.append(d)
return new_d
else:
text_filter = text_filter.lower()
for d in articles_dict:
for key_d, val in d.items():
if str(val).lower().find(text_filter) != -1:
new_d.append(d)
return new_d
Ответы (1 шт):
С точки зрения кода:
- Если у вас функция находит совпадения со словарем, то логично в нее этот словарь передавать.
- Переменная
articles_dict- в названии фигурирует словарь, а на деле это - список словарей, может ввести в заблуждение. - В цикле итерируетесь по
d.items(), но при этом ключ не используете. Тогда уже логичнее итерироваться поd.values(). - Так как вам не важен конкретный индекс совпадения строки, то лучше вместо функции
findиспользовать операторin. - Ваши вложенные циклы с условием прямо намекают на использование
list comprehenshions, такая запись будет более компактной и "питонячей". returnможно вынести в конец функции, поскольку у вас два взаимоисключающих условия, которые никогда не выполнятся одновременно.
Почитать подробнее про list comprehenshions можно здесь.
С точки зрения задачи:
Можно решить, используя следующий алгоритм:
- Преобразовываем список словарей в один список, содержащий все слова для поиска.
- В случае, если хотим произвести поиск без учета регистра, то все элементы списка преобразовываем в нижний регистр, то же самое с поисковой строкой.
- Пробегаемся по списку и находим требуемое совпадение.
Код:
def find_articles(text_filter, articles, letter_case=False):
list_words = [x for y in [list(x.values()) for x in articles] for x in y]
if not letter_case:
text_filter = text_filter.lower()
list_words = [str(x).lower() for x in list_words]
return any(text_filter in str(word) for word in list_words)
articles = [
{
"title": "Endless ocean waters.",
"author": "Jhon Stark",
"year": 2019,
},
{
"title": "Oceans of other planets are full of silver",
"author": "Artur Clark",
"year": 2020,
},
{
"title": "An ocean that cannot be crossed.",
"author": "Silver Name",
"year": 2021,
},
{
"title": "The ocean that you love.",
"author": "Golden Gun",
"year": 2021,
},
]
print(find_articles('End', articles, True)) # True
print(find_articles('END', articles, True)) # False
print(find_articles('END', articles, False)) # True