Как передать 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(), вместо того, чтобы пытаться ссылаться на второй аргумент.