Python: как мне вызвать `print` из` eval` в цикле? - PullRequest
3 голосов
/ 17 февраля 2012

Когда я звоню print с eval:

def printList(myList):
    maxDigits = len(str(len(myList)))
    Format = '0{0}d'.format(maxDigits)
    for i in myList:
        eval('print "#{0:' + Format + '}".format(i+1), myList[i]')

, выдает ошибку:

    print "#{0:01d}".format(i+1), myList[i]
        ^
SyntaxError: invalid syntax

Я пытался использовать this и переписал это:

def printList(myList):
    maxDigits = len(str(len(myList)))
    Format = '0{0}d'.format(maxDigits)
    for i in myList:
        obj = compile(src, '', 'exec')
        eval('print "#{0:' + Format + '}".format(i+1), myList[i]')

но это жалуется на i:

NameError: name 'i' is not defined

PS Я имею дело с python2.6

Ответы [ 4 ]

14 голосов
/ 17 февраля 2012

Вы не можете eval() a print: eval() используется для оценки выражения, а print является оператором.Если вы хотите выполнить инструкцию, используйте exec().Проверьте этот вопрос для лучшего объяснения :

>>> exec('print "hello world"')
hello world

Теперь вы можете передавать переменные localals (), если вы хотите сделать доступным i в exec:

>>> i = 1
>>> exec('print "hello world", i', locals())
hello world 1

Кроме того, в последнем написанном вами тесте вы компилируете () в режиме 'exec', который должен дать вам совет:)

7 голосов
/ 17 февраля 2012

Вам не нужно eval:

def printList(myList):
    maxDigits = len(str(len(myList)))
    str_format = '#{0:0' + str(maxDigits) + '}'
    for i, elem in enumerate(myList, 1):
        print str_format.format(i), elem

или, как заметил @SvenMarnach, вы можете поместить даже параметр форматирования в один вызов форматирования:

def printList(myList):
    maxDigits = len(str(len(myList)))
    for i, elem in enumerate(myList, 1):
        print '#{1:0{0}} {2}'.format(maxDigits, i, elem)
3 голосов
/ 17 февраля 2012

Чтобы сохранить код, делая его короче и проще для понимания:

def printList(myList):
    # int(math.log10(len(myList))+1) would be the appropriate way to do that:
    maxDigits = len(str(len(myList)))
    for i in myList:
        print "#{0:0{1}d}".format(i+1, maxDigits), myList[i]
1 голос
/ 17 февраля 2012

Упрощенное представление таково. Создайте формат отдельно от его использования. Избегайте eval().

    format =  "#{0:" + Format + "}"
    print format.format(i+1), myList[i]

Не делай вещи сложнее, чем они должны быть. Вот еще одна версия, которая строит формат за один шаг.

    format = '#{{0:0{0}d}}'.format(maxDigits)
    print format.format(i+1), myList[i]
...