(ответил 23 ноября '10 в 19:48)
Я не очень большой Pythoner - но я нашел этот синтаксис однажды, забыл, откуда, поэтому я решил, что я задокументирую это:
если вы используете sys.stdout.write
вместо print
( разница в том, что sys.stdout.write
принимает аргументы как функцию, в скобках - тогда как print
не ), то для единицы -Liner, вы можете изменить порядок команды и 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 Советы и хитрости - Первое издание - Python Tutorials | 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
.