Я пытаюсь выполнить некоторые из code golf, но все они требуют ввода, который нужно взять из stdin
. Как я могу получить это в Python?
Как вы читаете со стандартного ввода?
Ответ 1
Вы можете использовать модуль fileinput
:
import fileinput
for line in fileinput.input():
pass
fileinput
будет проходить по всем строкам ввода, указанным как имена файлов, заданные в аргументах командной строки, или стандартный ввод, если аргументы не предоставлены.
Примечание: line
будет содержать завершающий символ новой строки; чтобы удалить его используйте line.rstrip()
Ответ 2
Есть несколько способов сделать это.
-
sys.stdin
- это файл-подобный объект, на котором вы можете вызывать функцииread
илиreadlines
если вы хотите прочитать все или хотите все прочитать и разделить на новую строку автоматически. (Для этого вам нужноimport sys
.) -
Если вы хотите
raw_input
пользователя для ввода, вы можете использоватьraw_input
в Python 2.X и простоinput
в Python 3. -
Если вы просто хотите прочитать параметры командной строки, вы можете получить к ним доступ через список sys.argv.
Вы, вероятно, найдете эту статью в Википедии о вводе-выводе в Python также полезной ссылкой.
Ответ 3
import sys
for line in sys.stdin:
print(line)
Обратите внимание, что в конце будет добавлен символ новой строки. Чтобы удалить перевод строки в конце, используйте line.rstrip()
, как сказал @brittohalloran.
Ответ 4
Python также имеет встроенные функции input()
и raw_input()
. См. Документацию Python в Встроенные функции.
Например,
name = raw_input("Enter your name: ") # Python 2.x
или
name = input("Enter your name: ") # Python 3
Ответ 5
Здесь из Learning Python:
import sys
data = sys.stdin.readlines()
print "Counted", len(data), "lines."
В Unix вы можете проверить его, выполнив что-то вроде:
% cat countlines.py | python countlines.py
Counted 3 lines.
В Windows или DOS вы должны:
C:\> type countlines.py | python countlines.py
Counted 3 lines.
Ответ 6
Ответ, предложенный другими:
for line in sys.stdin:
print line
очень прост и pythonic, но следует отметить, что script будет ждать до EOF перед началом итерации по строкам ввода.
Это означает, что tail -f error_log | myscript.py
не будет обрабатывать строки, как ожидалось.
Правильный script для такого варианта использования:
while 1:
try:
line = sys.stdin.readline()
except KeyboardInterrupt:
break
if not line:
break
print line
UPDATE
Из комментариев было очищено то, что на python 2 может быть только буферизация, так что вы в конечном итоге ожидаете заполнения буфера или EOF до того, как выйдет запрос на печать.
Ответ 7
Как вы читаете со стандартного ввода в Python?
Я пытаюсь выполнить некоторые задачи кода, но все они требуют ввода от stdin. Как мне получить это в Python?
Вы можете использовать:
sys.stdin
- Файловый объект - вызовитеsys.stdin.read()
, чтобы прочитать все.input(prompt)
- передать ему необязательный запрос на вывод, он читает от стандартного ввода до первой новой строки, которую удаляет. Вам придется делать это несколько раз, чтобы получить больше строк, в конце ввода это вызывает EOFError. (Вероятно, не подходит для игры в гольф.) В Python 2 этоrawinput(prompt)
.open(0).read()
- В Python 3 встроенная функцияopen
принимает файловые дескрипторы (целые числа, представляющие ресурсы ввода-вывода операционной системы), а 0 - дескрипторstdin
. Он возвращает файл-подобный объект, такой какsys.stdin
- вероятно, ваш лучший выбор для игры в гольф. В Python 2 этоio.open
.open('/dev/stdin').read()
- аналогичноopen(0)
, работает на Python 2 и 3, но не на Windows (или даже Cygwin).fileinput.input()
- возвращает итератор над строками во всех файлах, перечисленных вsys.argv[1:]
, или stdin, если не указан. Используйте как''.join(fileinput.input())
.
И sys
, и fileinput
должны быть импортированы соответственно.
Быстрые примеры sys.stdin
, совместимые с Python 2 и 3, Windows, Unix
Вам просто нужно read
из sys.stdin
, например, если вы передаете данные в stdin:
$ echo foo | python -c "import sys; print(sys.stdin.read())"
foo
Мы видим, что sys.stdin
находится в текстовом режиме по умолчанию:
>>> import sys
>>> sys.stdin
<_io.TextIOWrapper name='<stdin>' mode='r' encoding='UTF-8'>
пример файла
Скажем, у вас есть файл, inputs.txt
, мы можем принять этот файл и записать его обратно:
python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt
Более длинный ответ
Здесь полная, легко воспроизводимая демонстрация с использованием двух методов: встроенной функции, input
(используйте raw_input
в Python 2) и sys.stdin
. Данные не изменены, поэтому обработка не является операцией.
Для начала давайте создадим файл для ввода:
$ python -c "print('foo\nbar\nbaz')" > inputs.txt
И используя код, который мы уже видели, мы можем проверить, что создали файл:
$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt
foo
bar
baz
Вот справка по sys.stdin.read
из Python 3:
read(size=-1, /) method of _io.TextIOWrapper instance
Read at most n characters from stream.
Read from underlying buffer until we have n characters or we hit EOF.
If n is negative or omitted, read until EOF.
Встроенная функция, input
(raw_input
в Python 2)
Встроенная функция input
считывает со стандартного ввода до новой строки, которая удаляется (дополняет print
, который по умолчанию добавляет новую строку.) Это происходит до тех пор, пока не получит EOF (конец файла), после чего она поднимается EOFError
.
Таким образом, вот как вы можете использовать input
в Python 3 (или raw_input
в Python 2) для чтения из stdin - поэтому мы создаем модуль Python, который мы называем stdindemo.py:
$ python -c "print('try:\n while True:\n print(input())\nexcept EOFError:\n pass')" > stdindemo.py
И давайте распечатаем его обратно, чтобы убедиться, что мы ожидаем:
$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < stdindemo.py
try:
while True:
print(input())
except EOFError:
pass
Опять же, input
читает до новой строки и по существу удаляет его из строки. print
добавляет новую строку. Поэтому, пока они оба изменяют ввод, их модификации отменяются. (Так что они по сути друг друга дополняют.)
И когда input
получает символ конца файла, он вызывает EOFError, которую мы игнорируем, а затем выходим из программы.
А в Linux/Unix мы можем передать из cat:
$ cat inputs.txt | python -m stdindemo
foo
bar
baz
Или мы можем просто перенаправить файл из стандартного ввода:
$ python -m stdindemo < inputs.txt
foo
bar
baz
Мы также можем выполнить модуль как скрипт:
$ python stdindemo.py < inputs.txt
foo
bar
baz
Вот справка по встроенному input
из Python 3:
input(prompt=None, /)
Read a string from standard input. The trailing newline is stripped.
The prompt string, if given, is printed to standard output without a
trailing newline before reading input.
If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError.
On *nix systems, readline is used if available.
sys.stdin
Здесь мы создаем демонстрационный скрипт, используя sys.stdin
. Эффективный способ перебора файловоподобного объекта заключается в использовании файловоподобного объекта в качестве итератора. Дополнительный метод записи в стандартный вывод этого ввода - просто использовать sys.stdout.write
:
$ python -c "print('import sys\nfor line in sys.stdin:\n sys.stdout.write(line)')" > stdindemo2.py
Распечатайте его обратно, чтобы убедиться, что он выглядит правильно:
$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < stdindemo2.py
import sys
for line in sys.stdin:
sys.stdout.write(line)
И перенаправить ввод в файл:
$ python -m stdindemo2 < inputs.txt
foo
bar
baz
Гольф в команде:
$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt
foo
bar
baz
Файловые дескрипторы для игры в гольф
Поскольку файловые дескрипторы для stdin
и stdout
равны 0 и 1 соответственно, мы также можем передать их в open
в Python 3 (не в 2, и обратите внимание, что нам все еще нужен 'w' для записи в stdout).
Если это работает в вашей системе, это сбрит больше символов.
$ python -c "open(1,'w').write(open(0).read())" < inputs.txt
baz
bar
foo
Python 2 io.open
также делает это, но импорт занимает гораздо больше места:
$ python -c "from io import open; open(1,'w').write(open(0).read())" < inputs.txt
foo
bar
baz
Обращение к другим комментариям и ответам
Один комментарий предлагает ''.join(sys.stdin)
для игры в гольф, но на самом деле он длиннее, чем sys.stdin.read() - плюс Python должен создать дополнительный список в памяти (то, как работает str.join
, когда нет списка) - для контраста:
''.join(sys.stdin)
sys.stdin.read()
Верхний ответ предполагает:
import fileinput
for line in fileinput.input():
pass
Но, поскольку sys.stdin
реализует файловый API, включая протокол итератора, он такой же, как и этот:
import sys
for line in sys.stdin:
pass
Другой ответ подсказывает это. Просто помните, что если вы делаете это в интерпретаторе, вам нужно сделать Ctrl - d, если вы работаете в Linux или Mac, или Ctrl - z в Windows (после Enter), чтобы отправить символ конца файла процессу. Кроме того, в этом ответе предлагается print(line)
- который добавляет '\n'
к концу - используйте вместо него print(line, end='')
(если в Python 2 вам понадобится from __future__ import print_function
).
Реальный вариант использования fileinput
предназначен для чтения в серии файлов.
Ответ 8
Это приведет к стандартному входу стандартного вывода:
import sys
line = sys.stdin.readline()
while line:
print line,
line = sys.stdin.readline()
Ответ 9
Основываясь на всех anwers с помощью sys.stdin
, вы можете также сделать что-то вроде следующего, чтобы читать из файла аргумента, если существует хотя бы один аргумент, и в противном случае вернуться к stdin:
import sys
f = open(sys.argv[1]) if len(sys.argv) > 1 else sys.stdin
for line in f:
# Do your stuff
и использовать его как
$ python do-my-stuff.py infile.txt
или
$ cat infile.txt | python do-my-stuff.py
или даже
$ python do-my-stuff.py < infile.txt
Это приведет к тому, что ваш Python script будет вести себя как многие программы GNU/Unix, такие как cat
, grep
и sed
.
Ответ 10
argparse
- это простое решение
Пример совместим с обеими версиями Python 2 и 3:
#!/usr/bin/python
import argparse
import sys
parser = argparse.ArgumentParser()
parser.add_argument('infile',
default=sys.stdin,
type=argparse.FileType('r'),
nargs='?')
args = parser.parse_args()
data = args.infile.read()
Вы можете запустить этот скрипт разными способами:
1. Использование стандартного stdin
echo 'foo bar' | ./above-script.py
или короче, заменив echo
на следующую строку:
./above-script.py <<< 'foo bar'
2. Использование аргумента имени файла
echo 'foo bar' > my-file.data
./above-script.py my-file.data
3. Использование stdin
через специальное имя файла -
echo 'foo bar' | ./above-script.py -
Ответ 11
Следующий чип кода поможет вам (он будет читать все блокировки stdin до EOF
в одну строку):
import sys
input_str = sys.stdin.read()
print input_str.split()
Ответ 12
Попробуйте следующее:
import sys
print sys.stdin.read().upper()
и проверьте его с помощью:
$ echo "Hello World" | python myFile.py
Ответ 13
Вы можете читать из stdin, а затем хранить входы в "данные" следующим образом:
data = ""
for line in sys.stdin:
data += line
Ответ 14
Считайте из sys.stdin
, но чтобы читать двоичные данные в Windows, вам нужно быть особенно осторожным, потому что sys.stdin
открывается в текстовом режиме, и это приведет к повреждению \r\n
, заменяющему их с \n
.
Решение состоит в том, чтобы установить режим в двоичный, если обнаружен Windows + Python 2, а на Python 3 используйте sys.stdin.buffer
.
import sys
PY3K = sys.version_info >= (3, 0)
if PY3K:
source = sys.stdin.buffer
else:
# Python 2 on Windows opens sys.stdin in text mode, and
# binary data that read from it becomes corrupted on \r\n
if sys.platform == "win32":
# set sys.stdin to binary mode
import os, msvcrt
msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
source = sys.stdin
b = source.read()
Ответ 15
Я очень удивлен, что никто пока не упоминал об этом хаке:
python -c "import sys;print (''.join([l for l in sys.stdin.readlines()]))"
совместим с python2 и python3
Ответ 16
Проблема с решением
import sys
for line in sys.stdin:
print(line)
заключается в том, что если вы не передадите какие-либо данные в stdin, он будет блокироваться навсегда. Вот почему я люблю этот ответ: сначала проверьте, есть ли какие-то данные по stdin, а затем прочитайте его. Это то, что я закончил:
import sys
import select
# select(files to read from, files to write to, magic, timeout)
# timeout=0.0 is essential b/c we want to know the asnwer right away
if select.select([sys.stdin], [], [], 0.0)[0]:
help_file_fragment = sys.stdin.read()
else:
print("No data passed to stdin", file=sys.stderr)
sys.exit(2)
Ответ 17
У меня возникли некоторые проблемы при работе с ним для чтения через сокеты, подключенные к нему. Когда сокет закрылся, он начал возвращать пустую строку в активном цикле. Так что это мое решение для меня (которое я тестировал только в Linux, но надеюсь, что он работает во всех других системах)
import sys, os
sep=os.linesep
while sep == os.linesep:
data = sys.stdin.readline()
sep = data[-len(os.linesep):]
print '> "%s"' % data.strip()
Итак, если вы начнете прослушивать сокет, он будет работать правильно (например, в bash):
while :; do nc -l 12345 | python test.py ; done
И вы можете вызвать его с помощью telnet или просто указать браузер на localhost: 12345
Ответ 18
Относительно этого:
for line in sys.stdin:
Я просто попробовал это на python 2.7 (после какого-то другого предложения) для очень большого файла, и я не рекомендую его именно по причинам, упомянутым выше (ничего не происходит в течение длительного времени).
В итоге у меня появилось несколько более питоническое решение (и оно работает с большими файлами):
with open(sys.argv[1], 'r') as f:
for line in f:
Затем я могу запустить script локально как:
python myscript.py "0 1 2 3 4..." # can be a multi-line string or filename - any std.in input will work
Ответ 19
n = int(raw_input())
for i in xrange(n):
name, number = raw_input().split()
Ответ 20
Один из вариантов - использовать функцию ввода, как показано ниже. Существует также метод raw_input, если вы не уверены в типе данных.
#!/usr/bin/env python
number = input("Please enter a number : ")
print("Entered number is %d" % number)
Запуск программы:
python test1.py
Please enter a number : 55
Entered number is 55
Ответ 21
Существует os.read(0, x)
который читает xbytes из 0, что представляет собой стандартный ввод. Это небуферизованное чтение, более низкий уровень, чем sys.stdin.read()
Ответ 22
Для Python 3 это будет:
# Filename e.g. cat.py
import sys
for line in sys.stdin:
print(line, end="")
Это в основном простая форма cat (1), так как она не добавляет символ новой строки после каждой строки. Вы можете использовать это (после того, как Вы отметили исполняемый файл, используя chmod +x cat.py
например:
echo Hello | ./cat.py
Ответ 23
При использовании команды -c
в качестве хитрого способа вместо чтения стандартного stdin
(и в некоторых случаях более гибкого) вы можете также передать команду сценария оболочки в команду python, поместив команду sell в кавычки в скобках, начинающихся с знак $
.
например
python3 -c "import sys; print(len(sys.argv[1].split('\n')))" "$(cat ~/.goldendict/history)"
Это будет подсчитывать количество строк из файла истории goldendict.