Переберите строку формата по списку - PullRequest
10 голосов
/ 02 июля 2010

В Лиспе вы можете получить что-то вроде этого:

(setf my-stuff '(1 2 "Foo" 34 42 "Ni" 12 14 "Blue"))
(format t "~{~d ~r ~s~%~}" my-stuff)

Каким был бы самый Pythonic способ перебора этого же списка? Первое, что приходит на ум, это:

mystuff = [1, 2, "Foo", 34, 42, "Ni", 12, 14, "Blue"]
for x in xrange(0, len(mystuff)-1, 3):
    print "%d %d %s" % tuple(mystuff[x:x+3])

Но мне просто неловко. Я уверен, что есть лучший способ?


Ну, если кто-то позже не предоставит лучший пример, я думаю, что решение gnibbler - самое лучшее \ самое близкое, хотя поначалу может быть не так очевидно, как оно делает то, что делает:

mystuff = [1, 2, "Foo", 34, 42, "Ni", 12, 14, "Blue"]
for x in zip(*[iter(mystuff)]*3):
    print "{0} {1} {2}".format(*x)

Ответы [ 6 ]

13 голосов
/ 02 июля 2010
mystuff = [1, 2, "Foo", 34, 42, "Ni", 12, 14, "Blue"]
for x in zip(*[iter(mystuff)]*3):
    print "%d %d %s"%x

Или используя .format

mystuff = [1, 2, "Foo", 34, 42, "Ni", 12, 14, "Blue"]
for x in zip(*[iter(mystuff)]*3):
    print "{0} {1} {2}".format(*x)

Если строка формата не жестко задана, вы можете проанализировать ее, чтобы определить, сколько терминов в строке

from string import Formatter
num_terms = sum(1 for x in Formatter().parse("{0} {1} {2}"))

Соединение всего этого дает

mystuff = [1, 2, "Foo", 34, 42, "Ni", 12, 14, "Blue"]
fmt = "{0} {1} {2}"
num_terms = sum(1 for x in Formatter().parse(fmt))
for x in zip(*[iter(mystuff)]*num_terms):
    print fmt.format(*x)
5 голосов
/ 02 июля 2010

Я думаю, join - самая похожая функция в Python:

(format t "~{~D, ~}" foo)

print(foo.join(", "))

Немного хуже, когда у вас есть несколько предметов внутри, как вы видите, хотя, если у вас есть группа с помощью функции (которая в любом случае действительно полезна!), я думаю, вы можете заставить ее работать без особых проблем.Что-то вроде:

mystuff = [1, 2, "Foo", 34, 42, "Ni", 12, 14, "Blue"]
print(["%d %d %s" % x for x in group(mystuff, 3)].join("\n"))
4 голосов
/ 02 июля 2010

Для начала, я бы использовал более новые методы форматирования строк в 2.6 +

print "{0} {1} {2}".format(*mystuff[x:x+3])
3 голосов
/ 02 июля 2010

Я бы сказал, что самый Pythonic будет сделать список глубже:

mystuff = [(1, 2, "Foo"), (34, 42, "Ni"), (12, 14, "Blue")]
for triplet in mystuff:
    print "%d %d %s" % triplet
2 голосов
/ 21 августа 2013
stuff = [1, 2, "Foo", 34, 42, "Ni", 12, 14, "Blue"]

it = iter(stuff)
itn = it.next

print '\n'.join("%d %d %s" % (el,itn(),itn())
                for el in it)

Очень понятно, я думаю

0 голосов
/ 21 августа 2013

Два лайнера на основе Райта:

mystuff = [1, 2, "Foo", 34, 42, "Ni", 12, 14, "Blue"]
print '\n'.join("{0},{1},{2}".format(*mystuff[x:x+3]) for x in xrange(0, len(mystuff)-1, 3))
...