(ответил 23 ноября 2010 года в 19:48)
Я на самом деле не большой Pythoner - но однажды я нашел этот синтаксис, забыл, откуда, поэтому я решил документировать его:
если вы используете sys.stdout.write
вместо print
( разница заключается в том, что sys.stdout.write
аргументы принимаются как функция, в скобках - тогда как print
нет ), то для однострочного вы можете избежать инвертирования порядка команды и for
удаления точки с запятой, и заключив команду в квадратные скобки, то есть:
python -c "import sys; [sys.stdout.write('rob\n') for r in range(10)]"
Понятия не имею, как этот синтаксис будет называться в Python :)
Надеюсь это поможет,
Ура!
(РЕДАКТИРОВАТЬ Вт 9 апреля 20:57:30 2013) Ну, я думаю, я наконец нашел, что эти квадратные скобки в однострочниках; они являются «списочным пониманием» (по-видимому); сначала отметьте это в Python 2.7:
$ STR=abc
$ echo $STR | python -c "import sys,re; a=(sys.stdout.write(line) for line in sys.stdin); print a"
<generator object <genexpr> at 0xb771461c>
Таким образом, команда в круглых скобках / скобках рассматривается как «объект генератора»; если мы «переберем» его, вызвав next()
- тогда будет выполнена команда внутри скобки (обратите внимание на «abc» в выходных данных):
$ echo $STR | python -c "import sys,re; a=(sys.stdout.write(line) for line in sys.stdin); a.next() ; print a"
abc
<generator object <genexpr> at 0xb777b734>
Если мы теперь используем квадратные скобки - обратите внимание, что нам не нужно вызывать next()
команду для ее выполнения, она выполняется сразу после назначения; Однако, спустя осмотр показывает , что a
это None
:
$ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; print a"
abc
[None]
Это не оставляет много информации для поиска в квадратных скобках - но я наткнулся на эту страницу, которая, я думаю, объясняет:
Python Tips And Tricks - Первое издание - Уроки Python | Dream.In.Code :
Если вы помните, стандартный формат однострочного генератора является своего рода одной строкой цикла for внутри скобок. Это создаст итеративный объект «один выстрел», представляющий собой объект, который вы можете перебирать только в одном направлении, и который вы не сможете использовать повторно, когда достигнете конца.
«Понимание списка» выглядит почти так же, как обычный однострочный генератор, за исключением того, что регулярные скобки - () - заменяются квадратными скобками - []. Основное преимущество понимания по списку состоит в том, что создается «список», а не итеративный объект «один выстрел», так что вы можете перемещаться по нему вперед и назад, добавлять элементы, сортировать и т. Д.
И действительно, это список - это просто его первый элемент, который становится ничем, как только он выполняется:
$ echo $STR | python -c "import sys,re; print [sys.stdout.write(line) for line in sys.stdin].__class__"
abc
<type 'list'>
$ echo $STR | python -c "import sys,re; print [sys.stdout.write(line) for line in sys.stdin][0]"
abc
None
Понимание списка иначе документировано в 5. Структуры данных: 5.1.4. Постижения списков - документация Python v2.7.4 как « Постижения списков обеспечивают краткий способ создания списков»; по-видимому, именно здесь ограниченная «выполнимость» списков вступает в игру в одну строку.
Что ж, надеюсь, я не так уж и плох
EDIT2: и вот однострочная командная строка с двумя не вложенными циклами for; оба заключены в квадратные скобки «понимание списка»:
$ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; b=[sys.stdout.write(str(x)) for x in range(2)] ; print a ; print b"
abc
01[None]
[None, None]
Обратите внимание, что второй «список» b
теперь имеет два элемента, поскольку цикл for явно запускается дважды; Однако результат sys.stdout.write()
в обоих случаях был (по-видимому) None
.