Как передать tuple1, если... else tuple2 в str.format?
Проще говоря, почему я получаю следующую ошибку?
>>> yes = True
>>> 'no [{0}] yes [{1}]'.format((" ", "x") if yes else ("x", " "))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: tuple index out of range
Я использую python 2.6.
Ответы
Ответ 1
☞ Функция индексирования:
При доступе к элементам аргументов в строке формата вы должны использовать индекс для вызова значения:
yes = True
print 'no [{0[0]}] yes [{0[1]}]'.format((" ", "x") if yes else ("x", " "))
{0[0]}
в строке формата равно (" ", "x")[0]
при вызове индекса tulple
{0[1]}
в строке формата равно (" ", "x")[1]
при вызове указателя tulple
☞ *
:
или вы можете использовать оператор *
для распаковки кортежа аргументов.
yes = True
print 'no [{0}] yes [{1}]'.format(*(" ", "x") if yes else ("x", " "))
При вызове оператора *
'no [{0}] yes [{1}]'.format(*(" ", "x") if yes else ("x", " "))
равно 'no [{0}] yes [{1}]'.format(" ", "x")
, если оператор True
☞ **
оператор (это дополнительный метод, когда ваш var is dict):
yes = True
print 'no [{no}] yes [{yes}]'.format(**{"no":" ", "yes":"x"} if yes else {"no":"x", "yes":" "})
Ответ 2
Используйте оператор *
, который принимает итерабельность параметров и поставляет каждый в качестве позиционного аргумента функции:
In [3]: 'no [{0}] yes [{1}]'.format(*(" ", "x") if yes else ("x", " "))
Out[3]: 'no [ ] yes [x]'
Ответ 3
Проблема заключается в том, что вы предоставляете только один аргумент string.format()
: кортеж. Когда вы используете {0}
и {1}
, вы ссылаетесь на 0-й и 1-й аргументы, переданные на string.format()
. Поскольку на самом деле нет 1-го аргумента, вы получаете сообщение об ошибке.
Оператор *, предложенный @Patrick Collins, работает потому, что он распаковывает аргументы в кортеже, превращая их в отдельные переменные. Это как если бы вы вызвали string.format( "," x") (или наоборот)
Опция индексации, предложенная @Tony Yang, работает, потому что она относится к отдельным элементам одного кортежа, переданным в format()
, вместо того, чтобы пытаться ссылаться на второй аргумент.