Я ищу предложения о том, как я мог бы переписать это, чтобы код не повторялся. Предполагается отделить число с плавающей запятой (цифры) от строки (буквенных символов) внутри значения словаря и вычесть или добавить числовой ввод пользователя к числу с плавающей запятой. После этого он объединяет цифры и буквы, преобразует их обратно в строку и сохраняет значение.
Пример того, что он должен сделать, — взять «19.0: курица» из словаря, разделить его, добавить 3 из введенных пользователем значений и вернуть в словарь «22.0 курица».
if modify_options == "1":
quantity_value = float(re.findall(r"[0-9]+(?:\.[0-9]*)?", inventory_list[key]) [0]) + quantity
quantity_measurement = ''.join(re.findall(r'(?i)[A-Z]', str(inventory_list[key])))
inventory_list[key] = str(quantity_value) + str(quantity_measurement)
return inventory_list
elif modify_options == "2":
quantity_value = float(re.findall(r"[0-9]+(?:\.[0-9]*)?", inventory_list[key])[0]) - quantity
quantity_measurement = ''.join(re.findall(r'(?i)[A-Z]', str(inventory_list[key])))
inventory_list[key] = str(quantity_value) + str(quantity_measurement)
return inventory_list
quantity_value = float(re.findall(r"[0-9]+(?:\.[0-9]*)?", inventory_list[key])[0]) + quantity * (1 if modify_options=='1' else -1)





Вы можете реорганизовать его за пару шагов. Во-первых, переместите общие операторы за пределы блоков if/else.
if modify_options in {"1", "2"}:
if modify_options == "1":
quantity_value = float(re.findall(r"[0-9]+(?:\.[0-9]*)?", inventory_list[key])[0]) + quantity
elif modify_options == "2":
quantity_value = float(re.findall(r"[0-9]+(?:\.[0-9]*)?", inventory_list[key])[0]) - quantity
quantity_measurement = ''.join(re.findall(r'(?i)[A-Z]', str(inventory_list[key])))
inventory_list[key] = str(quantity_value) + str(quantity_measurement)
return inventory_list
Затем вы можете переместить общий бит оператора quantity_value вверх и выполнять сложение или вычитание только внутри if/else.
if modify_options in {"1", "2"}:
quantity_value = float(re.findall(r"[0-9]+(?:\.[0-9]*)?", inventory_list[key])[0])
if modify_options == "1":
quantity_value += quantity
elif modify_options == "2":
quantity_value -= quantity
quantity_measurement = ''.join(re.findall(r'(?i)[A-Z]', str(inventory_list[key])))
inventory_list[key] = str(quantity_value) + str(quantity_measurement)
return inventory_list
Следующее должно работать с использованием модуля оператора . Вот об этом подробнее.
import operator
import re
def code_snippet(modify_options, inventory_list, key, quantity):
if modify_options == "1":
option = operator.add
elif modify_options == "2":
option = operator.sub
quantity_value = option(float(re.findall(r"[0-9]+(?:\.[0-9]*)?", inventory_list[key])[0]), quantity)
quantity_measurement = ''.join(re.findall(r'(?i)[A-Z]', str(inventory_list[key])))
inventory_list[key] = str(quantity_value) + str(quantity_measurement)
return inventory_list
я считаю, что это переработано с использованиемoperator.add/sub
Конечно @sahasrara62! Глядя выше, решение Malay Patra гораздо более пифоническое.
просто мое личное мнение, ничего страшного, просто личное мнение
Вы можете создать метод для выполнения этой задачи и использовать один шаблон, чтобы сделать ее более эффективной:
(?i)([0-9]+(?:\.[0-9]+)?)\s*:?\s*([\w]+)\s*
import re
def modify_inventory(inventories, key, quant, opts):
print(inventories[key])
q, m = re.findall(r"(?i)([0-9]+(?:\.[0-9]+)?)\s*:?\s*([\w]+)\s*", inventories[key])[0]
q = float(q)
q = q + quant if opts == "1" else q - quant if opts == "2" else q
inventories[key] = f"{q} {m}"
return inventories
inventories = {
'item1': '10.5 : potato',
'item2': '20 : egg',
'item3': '19.0 : chicken'
}
print(modify_inventory(inventories, 'item3', 3, '1'))
print(modify_inventory(inventories, 'item2', 3, '2'))
19.0 : chicken
{'item1': '10.5 : potato', 'item2': '20 : egg', 'item3': '22.0 chicken'}
20 : egg
{'item1': '10.5 : potato', 'item2': '17.0 egg', 'item3': '22.0 chicken'}
Лучше всего для этого заключить код в функцию. Фактически, всякий раз, когда вы обнаруживаете, что какая-то часть кода повторяется несколько раз, вы должны поместить ее в функцию.
Вот как это сделать:
def update_inventory(key, option, quantity):
quantity_value = float(re.findall(r"[0-9]+(?:\.[0-9]*)?", inventory_list[key]) [0])
quantity_measurement = ''.join(re.findall(r'(?i)[A-Z]', str(inventory_list[key])))
if option= = "1":
quantity_value += quantity
elif option= = "2":
quantity_value -= quantity
inventory_list[key] = str(quantity_value) + str(quantity_measurement)
return inventory_list
#now you can update the inventory_list by calling the function
update_inventory(2, "1", 9)
update_inventory(1, "2", 4)
Это уже есть в функции, поскольку есть операторы return.
Это правда, но внешняя функция, вероятно, предназначена для какой-то другой цели, нет ничего плохого в том, чтобы объявить функцию обновления отдельно и использовать ее внутри функции.
Если вы собираетесь изменить inventory_list на месте (как глобальную переменную или параметр функции), верните None. Верните список, если вы собираетесь создать новый список на основе аргумента.
Поместите повторяющийся код в функцию. Кажется, единственное, что отличается, это
quantity, который вы можете считать положительным или отрицательным в зависимости отmodify_options, т. е. f 1+quantityи если 2+(-quantity)