【问题标题】:Python: C++-like stream inputPython:类 C++ 流输入
【发布时间】:2010-09-29 21:11:33
【问题描述】:

是否有一种 Python 式的读取方式——比如说——混合整数和字符输入,而无需一次读取整个输入,也不必担心换行符?例如,我有一个包含空格分隔数据的文件,我只知道其中有 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 并且该函数应该能够将它们返回为输入一条线。 :)

【问题讨论】:

    标签: c++ input stream python


    【解决方案1】:

    像这样?

    >>> 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]
    

    【讨论】:

    • 哇,使用 map(int, aList) 是我不会想到的。不错:-)
    • 不 data = someFile.read() 读取整个文件(这是问题试图避免的)?
    • 是的,但是...问题主要在于增量解析和忽略换行符。 “不阅读整个输入”有时是似是而非的(除非您的文件是几个 Gb)。
    【解决方案2】:

    如果你不想一次读一整行,你可能想尝试这样的事情:

    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
    

    应该在文件中生成每个以空格分隔的标记,一次读取一个字符。从那里你应该能够将它们转换为它们应该是的任何类型。空格也可以处理得更好。

    【讨论】:

      【解决方案3】:

      一个返回令牌流并表现得像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()))
      

      【讨论】:

        【解决方案4】:

        这是怎么回事?以 heikogerlach 的优秀 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) ]
        

        【讨论】:

          猜你喜欢
          • 2010-11-04
          • 2014-02-04
          • 2012-09-06
          • 2010-10-02
          • 2014-03-06
          • 2012-11-26
          • 1970-01-01
          • 1970-01-01
          • 2011-12-28
          相关资源
          最近更新 更多