Differences between enumerate (fileinput.input (file)) and enumeration (file)

I am looking for some help with my code below:

for file in file_name : if os.path.isfile(file): for line_number, line in enumerate(fileinput.input(file, inplace=1)): print file os.system("pause") if line_number ==1: line = line.replace('Object','#Object') sys.stdout.write(line) 

I wanted to modify some previous extracted files to build them using matplotlib. To do this, I delete some lines by commenting on some others.

My problem is this:

  • Using for line_number, line in enumerate(fileinput.input(file, inplace=1)): gives me only 4 of the 5 previous extracted files (when viewing a list of file_files it contains 5 links!)

  • Using for line_number, line in enumerate(file): gives me 5 previous extracted files, BUT I don't know how to make changes using the same file without creating another ...

Do you have an idea on this issue? Is this a normal problem?

+6
source share
2 answers

There are a few things that can help you.

First, file_name is represented as a list of file names. It might be better called file_names , and then you can use file_name for each of them. You have confirmed that it has 5 entries.

The enumerate() function is used to enumerate a list of elements to provide both an index and an element for each cycle. This saves you from having to use a separate counter variable, for example.

 for index, item in enumerate(["item1", "item2", "item3"]): print index, item 

will print:

 0 item1 1 item2 2 item3 

This is not required since you decided to use the fileinput library. This is intended to take a list of files and iterate over all lines in all files in one cycle. Thus, you need to tweak your approach a little, considering that your list of files is called file_names , then you write something like this:

 # Keep only files in the file list file_names = [file_name for file_name in file_names if os.path.isfile(file_name)] # Iterate all lines in all files for line in fileinput.input(file_names, inplace=1): if fileinput.filelineno() == 1: line = line.replace('Object','#Object') sys.stdout.write(line) 

The main point here is that it is better to pre-filter any non-file names before transferring the list to fileinput . I will leave it for you to fix the exit.

fileinput provides a number of functions to help you determine which file or line number is currently being processed.

+2
source

Assuming you still have problems, my typical approach is to open the file for reading only, read its contents in a variable, close the file, make the variable edited , open the file for writing (erase the original file), and finally write the contents edited .

I like this approach, because I can just change the filename to be written out if I want to test my changes without destroying the original file.

In addition, I recommend calling containers using multiple nouns, for example, @Martin Evans suggests.

 import os file_names = ['file_1.txt', 'file_2.txt', 'file_3.txt', 'file_4.txt', 'file_5.txt'] file_names = [x for x in file_names if os.path.isfile(x)] # see @Martin answer again for file_name in file_names: # Open read-only and put contents into a list of line strings with open(file_name, 'r') as f_in: lines = f_in.read().splitlines() # Put the lines you want to write out in out_lines out_lines = [] for index_no, line in enumerate(lines): if index_no == 1: out_lines.append(line.replace('Object', '#Object')) elif ... else: out_lines.append(line) # Uncomment to write to different file name for edits testing # with open(file_name + '.out', 'w') as f_out: # f_out.write('\n'.join(out_lines)) # Write out the file, clobbering the original with open(file_name, 'w') as f_out: f_out.write('\n'.join(out_lines)) 

The downside with this approach is that each file must be small enough to be inserted into memory twice ( lines + out_lines ).

Good luck

0
source

Source: https://habr.com/ru/post/989622/


All Articles