Python: C ++ - как поток ввода - PullRequest
2 голосов
/ 06 января 2009

Есть ли питонный способ чтения, скажем, смешанного целочисленного и символьного ввода, не считывая весь ввод сразу и не беспокоясь о переносах строк? Например, у меня есть файл с разделенными пробелами данными, о которых я знаю только, что есть x целых чисел, затем y символов и затем еще z целых чисел. Я не хочу ничего говорить о переводе строк.

Я имею в виду нечто такое же бессмысленное, как следующее в C ++:

...

int i, buf;
char cbuf;
vector<int> X, Z;
vector<int> Y;

for (i = 0; i < x; i++) {
    cin >> buf;
    X.push_back(buf);
}

for (i = 0; i < y; i++) {
    cin >> cbuf;
    Y.push_back(cbuf);
}

for (i = 0; i < z; i++) {
    cin >> buf;
    Z.push_back(buf);
}

РЕДАКТИРОВАТЬ: я забыл сказать, что я хотел бы, чтобы он хорошо себя вел и при живом вводе данных с консоли - т.е. не должно быть необходимости нажимать Ctrl + D перед получением токенов, и функция должна иметь возможность возвращать их как как только строка была введена. :)

Ответы [ 4 ]

6 голосов
/ 06 января 2009

Как насчет небольшой функции-генератора, которая возвращает поток токенов и ведет себя как cin:

def read_tokens(f):
   for line in f:
       for token in line.split():
           yield token

x = y = z = 5  # for simplicity: 5 ints, 5 char tokens, 5 ints
f = open('data.txt', 'r')
tokens = read_tokens(f)
X = []
for i in xrange(x):
    X.append(int(tokens.next()))
Y = []
for i in xrange(y):
    Y.append(tokens.next())
Z = []
for i in xrange(z):
    Z.append(int(tokens.next()))
3 голосов
/ 06 января 2009

Если вы не хотите читать всю строку за раз, вы можете попробовать что-то вроде этого:

def read_tokens(file):
    while True:
        token = []
        while True:
            c = file.read(1)
            if c not in ['', ' ', '\t', '\n']:
                token.append(c)
            elif c in [' ', '\t', '\n']:
                yield ''.join(token)
                break
            elif c == '':
                yield ''.join(token)
                raise StopIteration

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

2 голосов
/ 06 января 2009

Как это?

>>> data = "1 2 3 4 5 6 abcdefg 9 8 7 6 5 4 3"

Например, мы можем получить это с data= someFile.read()

>>> fields= data.split()
>>> x= map(int,fields[:6])
>>> y= fields[6]
>>> z= map(int,fields[7:])

Результаты

>>> x
[1, 2, 3, 4, 5, 6]
>>> y
'abcdefg'
>>> z
[9, 8, 7, 6, 5, 4, 3]
0 голосов
/ 07 января 2009

Как это? Опираясь на отлично Хейкогерлаха read_tokens.

def read_tokens(f):
   for line in f:
       for token in line.split():
           yield token

Мы можем выполнить следующие действия, чтобы подобрать 6 цифр, 7 символов и 6 цифр.

fi = read_tokens(data)
x= [ int(fi.next()) for i in xrange(6) ]
y= [ fi.next() for i in xrange(7) ]
z= [ int(fi.next()) for i in xrange(6) ]
...