Python:在循环中写入文件读取该文件?

时间:2017-01-04 19:40:50

标签: python-2.7 for-loop file-io

我想知道,在python(windows)中,我是否可以在同一个循环结构中写入文件指针,而我正在从同一个文件中读取。

如果我希望附加到文件流并继续读取处理(包括写入的数据),那么以下工作会是什么?:

dict

每当我更改一个我正在迭代的对象时(例如删除col_1 <- c(1,2,NA,4,5) temp_col_1 <-c(12,2,2,3,4) col_2 <- c(1,23,423,NA,23) temp_col_2 <-c(1,2,23,4,5) df_test<-data.frame(col_1,temp_col_1,col_2, temp_col_2) temp_cols <- names(df_test)[grepl("^temp", names(df_test))] cols <- sub("^temp_", "", temp_cols) for (i in seq_along(temp_cols)){ row_to_replace <- which(is.na(df_test[[cols[i]]])) df_test[[cols[i]]][row_to_replace] <- df_test[[temp_cols[i]]][row_to_replace] } df_test col_1 temp_col_1 col_2 temp_col_2 1 1 12 1 1 2 2 2 23 2 3 2 2 423 23 4 4 3 4 4 5 5 4 23 5 中我正在迭代的项目),我以前遇到过python balking的问题,但是因为我不是在这种情况下更改文件指针本身,有什么问题吗?如果我读过的行是文件的最后一行,那么答案会有所不同吗?

我对python 2.7特别好奇,但是如果py3 +的答案有所不同,我相信我最终也会对它感激不尽。

1 个答案:

答案 0 :(得分:0)

回答我自己的问题:py2.7,以下作品,虽然令人费解。注意,由于预读&#34;优化&#34;我无法使用fit=lm(Mydata~I(Year-1950))语法。在python中。

for line in f

输出:

import base64, os

csvstring = "this,is,a,csv,string\r\nthis,is,another,such,string"
b64string = base64.b64encode(csvstring).decode('utf-8')

f = open('myfile.xyz', "w+b")
f.write(b64string+os.linesep)
f.write(b64string) # no final \n to test case where file doesn't end in \n
f.close()

fmode = "a+b"
f = open('myfile.xyz', fmode)
f.seek(0,os.SEEK_END)
eofpos = f.tell() # aka writepos
try:
  if not eofpos: raise EOFError
  f.seek(eofpos-1, os.SEEK_SET)
  lastchar = f.read(1).replace("\r","\n") # if not \n (or \r), we'll have to append the eol before writing anything else
except (EOFError,IOError,OSError):
  eofpos = 0
  lastchar="\n" # we don't have to add
  eol = os.linesep if fmode.endswith("b") else "\n"
f.seek(0, os.SEEK_SET)
firstline = True
linecount = 0
readpos = 0
while 1:
  line = f.readline()
  if not line: break # while (line = f.readline()): # empty string is False
#for line in f:
  """
  can't use `for line in f`, due to read-ahead of file object
  (see https://docs.python.org/2/library/stdtypes.html#file.next)
  When a file is used as an iterator, typically in a for loop (for example, for line in f: print line),
  the next() method is called repeatedly. This method returns the next input line, or raises StopIteration when EOF is hit.
  In order to make a for loop the most efficient way of looping over the lines of a file (a very common operation),
  the next() method uses a hidden read-ahead buffer. As a consequence of using a read-ahead buffer, combining next()
  with other file methods (like readline()) does not work right. However, using seek() to reposition the file to an absolute
  position will flush the read-ahead buffer.
  """
  linecount += 1
  l = line.rstrip("\n\r") # get rid of terminal end-of-line characters, regardless of the order
  print("{}: {} ({})".format(linecount, l, line.replace("\r","\\r").replace("\n","\\n")))
  if firstline:
    if fmode.endswith("b"):
      if len(l) != len(line):
        eol = line[len(l):] # grab the end of line used elsewhere in this file, so as to not throw off the file reader later
      else:
        eol = os.linesep
    else: # text files, don't use linesep, use \n
      eol = "\n"
    firstline = False
  if (len(l)):
    if l.count(',') < 2:
      print("\tLine {} with insufficient delimiters (,) encountered. Trying to see if it's encoded. length {} line: {}".format(linecount,len(l),l))
      try:
        prepend = '' if (lastchar == '\n') else eol
        testme = prepend + base64.b64decode(l).decode('utf-8', errors='ignore') + eol
        if testme.count(',') >= 1: # here we'll just require 2+ items
          readpos = f.tell()
          f.seek(eofpos,os.SEEK_SET) # otherwise after a read, the filepointer is set back to the original eol before write
          f.write(testme)
          eofpos += len(testme)
          f.flush() # otherwise the write may be thrown out with subsequent re-writes
          f.seek(readpos,os.SEEK_SET)
          lastchar = '\n' # the end of file should now either be \r or \r\n after the next write
      except (TypeError,UnicodeError): # e.g. padding error
        print("\t\tWARNING: line not able to be unencoded")
      except (EOFError,IOError,OSError):
        print("\t\tERROR: writing unencoded data back to file")
    else: # 3 or more items, 2 or more commas
      datstrm = l.split(",")
      print("\t{} item line {} OK: {}".format(len(datstrm),linecount,l))
  else:
    print("\tBlank line encountered at line {}".format(linecount))
f.close()