Censor the middle of words of length N from a text file
create_censor_file should really be called create_censored_file.
I'd rename source to source_file for consistency and clarity.
You should use with for both files.
Why not use just w instead of w+?
This is probably one of the few things that regexes are actually useful for. You can just use re.sub(r'(?&lt;=\b\w)\w{' + ','.join(map(lambda x: str(x-2), LENGTHS_TO_CENSOR)) + '}(?=\w\b)', lambda match: CENCOR_CHAR * len(match.group(0)), source.read())


A couple other things:


Good job with the main function and if __name__ == '__main__' check!
I have not yet tested this code.


Result:

LENGTHS_TO_CENSOR = {4, 5}
CENSOR_CHAR       = '*'
CENSOR_EXT        = "-censored"

def create_censor_file(filename):       
    with open(filename + CENSOR_EXT, "w") as output_file, open(filename) as source_file:
        output_file.write(
            re.sub(
                r'(?&lt;=\b\w)\w{'
                    + ','.join(map(lambda x: str(x-2), LENGTHS_TO_CENSOR))
                    + '}(?=\w\b)',
                lambda match: CENSOR_CHAR * len(match.group(0)),
                source_file.read()))

def main():
    filename = input("File to be censored: ")
    create_censor_file(filename)

if __name__ == "__main__":
    main()