динамический формат строки из кортежей кортежа с использованием Python

1

В приведенном ниже примере сценарий 1 работает нормально как в коде (Code 1, так и в коде 2). Но сценарий 2 не работает в коде 1.

Мое требование Tuple должно продолжать повторяться, пока оно не заполнит всю строку форматирования в запросе динамически. Потому что, где предложения не являются постоянными для всех запросов.

Сценарий 1 #

query = SELECT * FROM test.order where total_price in {}

Кортеж:

finTup=((125, 125, 125, 125),)
SELECT * FROM test.order where total_price in (125, 125, 125, 125)

Сценарий 2 #

query = SELECT * FROM test.order WHERE order_id IN {} AND product_id IN {}

Кортеж:

finTup=((101, 105, 106, 107), (2, 2, 2, 2))

Код 1:

frt = 'finTup[{}]'
half = ''
val = ''
i = 0
le = len(finTup)
for i in range(le):
    print(i)
    print(eval(frt.format(i)))
    if i == le -1:
        half = half + frt.format(i)
        val = val + " " + frt.format(i)
    else:
        half = half + frt.format(i)+', '
        val = val + " " + frt.format(i)+', '
temp2 = query.format(eval(val))

Код 2:

if le == 1:
     query = query.format(finTup[0])
elif le == 2:
      query = query.format(finTup[0], finTup[1])
 elif le == 3:
       query = query.format(finTup[0], finTup[1], finTup[2])
elif le == 4:
       query = query.format(finTup[0], finTup[1], finTup[2], finTup[3])

Error:
temp2 = query.format(eval(val))
IndexError: tuple index out of range

Пожалуйста, помогите мне исправить это.

  • 0
    Код 2 является статическим, который мне нужно заменить на динамический код.
  • 0
    Дайте подходящий ввод и вывод
Показать ещё 1 комментарий
Теги:
python-3.x
string-formatting

1 ответ

2
Лучший ответ

TL; DR

Здравствуйте, у вас есть эта ошибка, потому что вы пытаетесь предоставить один аргумент функции format которая ожидает два параметра (так как у вас есть 2 {}).

Примечание. Избегайте использования функции eval... Это довольно не рекомендуется, даже в той ситуации, в которой вы сейчас находитесь. Все можно сделать без оценки str.


В дальнейшем я запускаю код для сценария № 2, т.е.

query2 = """SELECT * FROM test.order WHERE order_id IN {} AND product_id IN {}"""
finTup = ((101, 105, 106, 107), (2, 2, 2, 2))

Шаг 1: Отладка

Представим, что вы обновляете свой код для отладки следующим образом:

frt = 'finTup[{}]'
half = ''
val = ''
i = 0 # btw, you don't need to initialize i here
le = len(finTup)

for i in range(le):
    if i == le -1:
        half = half + frt.format(i)
        val = val + " " + frt.format(i)
    else:
        half = half + frt.format(i)+', '
        val = val + " " + frt.format(i)+', '

print val
print eval(val)

temp2 = query.format(eval(val))

Ваш результат должен быть:

 vars[0],  vars[1]
((101, 105, 106, 107), (2, 2, 2, 2))

Итак, представьте, что вы пишете код python из вышеприведенного вывода, что бы вы сделали:

query.format(((101, 105, 106, 107), (2, 2, 2, 2)))

Фактически вы предоставляете один параметр tuple типа с двумя элементами. Но важно то, что вы предоставляете format с одним параметром. Функция format попытается получить доступ ко второму параметру, который вы не предоставляете. Это ломает.


Шаг 2: Фиксация кода

Посмотрите на эту статью SO. Он показывает вам, как использовать оператор *. Он в основном преобразует list или tuple в последовательность элементов. Идеально подходит для параметров функций и т.д.

Итак, применительно к вашему текущему делу:

temp2 = query.format(*eval(val))

И трюк сделан.


Шаг 3: Оптимизация

Теперь позвольте испортить код 1 и используйте то, что мы узнали, с кодом 2. Нам нужно распаковать tuple tuple в параметры для подачи в format. Итак, почему бы просто не сделать:

# I renamed 'finTup' to 'vars' since I don't know what it means
def get_query(query, vars):
    return query.format(*vars)

Он в основном объединяет логику кода 1 и кода 2 в одну строку.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню