简体   繁体   中英

Check if value exists in file

I am trying to read the following file line by line and check if a value exists in the file. What I am trying currently is not working. What am I doing wrong?

If the value exists I do nothing. If it does not then I write it to the file.

file.txt:

123
345
234
556
654
654

Code:

file = open("file.txt", "a+")
lines = file.readlines()
value = '345'
if value in lines:
    print('val ready exists in file')
else:
    # write to file
    file.write(value)

There are two problems here:

  • .readlines() returns lines with \n not trimmed, so your check will not work properly.
  • a+ mode opens a file with position set to the end of the file . So your readlines() currently returns an empty list!

Here is a direct fixed version of your code, also adding context manager to auto-close the file

value = '345'
with open("file.txt", "a+") as file:
    file.seek(0) # set position to start of file
    lines = file.read().splitlines() # now we won't have those newlines
    if value in lines:
        print('val ready exists in file')
    else:
        # write to file
        file.write(value + "\n") # in append mode writes will always go to the end, so no need to seek() here

However, I agree with @RoadRunner that better is to just use r+ mode; then you don't need the seek(0) . But the cleanest is just to split out your read and write phases completely, so you don't run into file position problems.

I would consider several changes.

1: Use with to automatically close the file.
2: Use strip() to remove leading or trailing stuff, like \n
3: Use a break for the loop.
4: Add \n in the write part.

value = "345"
with open("file.txt", "a+") as file:
    file.seek(0)
    for line in file.readlines():
        if line.strip("\n") == value:
            print('val ready exists in file')
            break
    else:
        # write to file
        file.write(f"\n{value}")

when working with io the recomended approach is to use the context manager . Context managers allow you to allocate and release resources precisely when you want to. The most widely used example of context managers is the with statement. if you have a large file better not to use file.readlines() or the read() method. The readlines() method returns a list containing each line in the file as a list item. better to iterate on the file stream line by line (generator). always use try except with io operations: :

values=['123','233'...]
try:
    with open("file.txt", "r+") as fp:
        for line in fp:
            for val in values:
                if val not in line.strip():
                    fp.write(val)
                else:
                    print('val ready exists in file')
except (OSError,...): #catch what ever you think this code above can raise, and re raise in except block if you want.
#do exception handling

Since you want to open the file for reading and writing, I suggest using the r+ mode from open() . This will open the file at the beginning of the file, since we want to first read all lines. Using a+ will open the file for reading and writing at the end of the file, which will cause lines to give you an empty list from readlines() .

You also need to strip newlines from lines before checking if the value exists. This is because 345 is not equal to 345/n . We can use a list comprehension to strip the newlines from lines using str.rstrip() , which strips whitespace from the right. Additionally, If you have to do repetitive lookups for multiple values, it might be worth converting lines to a set for constant time lookups, instead of doing a linear search with a list.

Its also worth using With Statement Context Managers when reading files, since the closing of the file is handled for you.

value = '345'

with open("file.txt", mode="r+") as file:
    lines = [line.rstrip() for line in file.readlines()]

    if value in lines:
        print('value ready exists in file')
    else:
        file.write(f"{value}\n")

The other choice is to use f.seek(0) with a+ to set the position at the beginning of the file, as shown in @Cihan Ceyhan's answer. However I think this overcomplicates things, and its just easier to use the r+ mode.

This should work:)

filename = 'file.txt'
value = '345'

with open(filename) as f:
    if value in f.read(): # read if value is in file 
        print('Value is in the file')

This will check if the value is in the file and if it's not there. It will add value to the file.

filename = 'file_1.txt'
value = '999'

with open(filename, 'r+') as f:
    if value in f.read():
        print(f"Value {value} is in the file")
    else:
        print("The value not in the file.\nTherefore, saving the value in the file.")
        f.write(f"{value}\n")

When you are opening file in " a+ " mode the file cursor from where the readlines() method will start reading will be at the end so readlines would read nothing. You need to do f.seek(0) in order to move the cursor to the beginning.

file = open("file.txt", "a+")
file.seek(0)
lines = [line.strip() for line in file.readlines()]
print(lines)

value = '345'
if value in lines:
    print('val ready exists in file')
else:
    print("else")
    # write to file
    file.write(value)
file.close()

Your python script works for me properly. I guess the last line in the else statement should be file.write(value) instead of file.write(val) .

The readlines() method returns a list containing \n with each element so when the condition is checked it is not compared with value with \n so the statement is always false so i have a code that solve your problem.

f_name = "file.txt"
text = "102"
def check_in_file(file_name, value):
    with open(file_name, 'r') as read_obj:
        for line in read_obj:
            if value in line:
                return True
    return False
if check_in_file(f_name, text):
    print('Yes, string found in file')
else:
    print('String not found in file')
    file = open(f_name, 'a')
    file.write("\n"+text)
    file.close()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM