Как вы читаете со стандартного ввода?

Я пытаюсь выполнить некоторые из code golf, но все они требуют ввода, который нужно взять из stdin. Как я могу получить это в Python?

1295
20 сент. '09 в 8:48
источник поделиться
22 ответов

Вы можете использовать модуль fileinput:

import fileinput

for line in fileinput.input():
    pass

fileinput будет проходить по всем строкам ввода, указанным как имена файлов, заданные в аргументах командной строки, или стандартный ввод, если аргументы не предоставлены.

Примечание: line будет содержать завершающий символ новой строки; чтобы удалить его используйте line.rstrip()

869
21 сент. '09 в 16:01
источник

Связанные вопросы


Похожие вопросы

Есть несколько способов сделать это.

  • sys.stdin - это файл-подобный объект, на котором вы можете вызывать функции read или readlines если вы хотите прочитать все или хотите все прочитать и разделить на новую строку автоматически. (Для этого вам нужно import sys.)

  • Если вы хотите raw_input пользователя для ввода, вы можете использовать raw_input в Python 2.X и просто input в Python 3.

  • Если вы просто хотите прочитать параметры командной строки, вы можете получить к ним доступ через список sys.argv.

Вы, вероятно, найдете эту статью в Википедии о вводе-выводе в Python также полезной ссылкой.

648
20 сент. '09 в 8:53
источник
import sys

for line in sys.stdin:
    print line
376
20 июля '10 в 13:30
источник

Python также имеет встроенные функции input() и raw_input(). См. Документацию Python в Встроенные функции.

Например,

name = raw_input("Enter your name: ")   # Python 2.x

или

name = input("Enter your name: ")   # Python 3
201
03 марта '11 в 22:05
источник

Здесь из 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.
175
20 сент. '09 в 8:51
источник

Ответ, предложенный другими:

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 до того, как выйдет запрос на печать.

92
30 сент. '11 в 12:08
источник

Как вы читаете stdin на Python?

Я пытаюсь выполнить некоторые проблемы с кодом для кодов, но все они требуют ввода данных из stdin. Как это получить на Python?

Ты можешь использовать:

  • sys.stdin - Файл-подобный объект - вызовите sys.stdin.read() чтобы прочитать все.
  • input(prompt) - передать ему необязательное приглашение для вывода, оно читается от stdin до первой новой строки, которую он разделяет. Вам нужно будет сделать это несколько раз, чтобы получить больше строк, в конце ввода он вызывает EOFError. (Вероятно, это не очень хорошо для игры в гольф.) В Python 2 это rawinput(prompt).
  • open(0).read() - В Python 3 open принимают дескрипторы файлов (целые числа, представляющие ресурсы IO операционной системы), а 0 - дескриптор stdin. Он возвращает файл-подобный объект, такой как sys.stdin - вероятно, ваш лучший sys.stdin для игры в гольф.
  • open('/dev/stdin').read() - похоже на open(0), работает на Python 2 и 3, но не на Windows (или даже на Cygwin).
  • fileinput.input() - возвращает итератор по строкам во всех файлах, перечисленных в sys.argv[1:], или stdin, если не указан. Используйте как. ''.join(fileinput.input()).

fileinput необходимо импортировать как sys и fileinput.

Быстрые примеры sys.stdin совместимые с Python 2 и 3, Windows, Unix

Вам просто нужно read sys.stdin, например, если вы sys.stdin данные в stdin:

$ echo foo | python -c "import sys; print(sys.stdin.read())"
foo

пример файла

Скажем, у вас есть файл, 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

Здесь help на 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, которая по умолчанию добавляет новую EOFError). Это происходит до тех пор, пока не получит EOF (End Of File), после чего он вызывает 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

Или мы можем просто перенаправить файл из stdin:

$ 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. Эффективный способ итерации по файлоподобному объекту - использовать файл-подобный объект как итератор. Дополнительный метод записи в stdout из этого ввода состоит в том, чтобы просто использовать 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 предназначен для чтения в серии файлов.

74
30 июля '16 в 7:10
источник

Это приведет к стандартному входу стандартного вывода:

import sys
line = sys.stdin.readline()
while line:
    print line,
    line = sys.stdin.readline()
35
09 авг. '12 в 19:31
источник

Основываясь на всех 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.

30
29 июля '13 в 18:04
источник

Следующий чип кода поможет вам (он будет читать все блокировки stdin до EOF в одну строку):

import sys
input_str = sys.stdin.read()
print input_str.split()
14
25 янв. '16 в 13:26
источник

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
27 сент. '18 в 16:40
источник

Вы можете читать из stdin, а затем хранить входы в "данные" следующим образом:

data = ""
for line in sys.stdin:
    data += line
7
21 июля '14 в 0:33
источник

Попробуйте следующее:

import sys

print sys.stdin.read().upper()

и проверьте его с помощью:

$ echo "Hello World" | python myFile.py
7
27 авг. '13 в 18:43
источник

Я очень удивлен, что никто пока не упоминал об этом хаке:

python -c "import sys;print (''.join([l for l in sys.stdin.readlines()]))"

совместим с python2 и python3

6
07 нояб. '16 в 13:08
источник

Считайте из 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()
5
14 авг. '16 в 8:12
источник

Проблема с решением

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)
3
02 нояб. '17 в 11:49
источник

У меня возникли некоторые проблемы при работе с ним для чтения через сокеты, подключенные к нему. Когда сокет закрылся, он начал возвращать пустую строку в активном цикле. Так что это мое решение для меня (которое я тестировал только в 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

2
29 окт. '14 в 17:57
источник
n = int(raw_input())
for i in xrange(n):
    name, number = raw_input().split()
1
29 марта '18 в 8:15
источник

Относительно этого:

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
1
09 июня '16 в 2:02
источник

Один из вариантов - использовать функцию ввода, как показано ниже. Существует также метод 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

Ссылка: http://www.python-course.eu/input.php

0
22 нояб. '16 в 1:12
источник

Для 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
0
04 мая '19 в 21:23
источник

Существует os.read(0, x) который читает xbytes из 0, что представляет собой стандартный ввод. Это небуферизованное чтение, более низкий уровень, чем sys.stdin.read()

0
15 апр. '19 в 20:29
источник

Посмотрите другие вопросы по меткам или Задайте вопрос