-2

I was trying to slice the extension '.txt' from some file names.

It look like the Python cut the last letter - before the dot- if its a t or x:

filenames = ["report.txt", "downloads.txt", "success.txt", "folders.txt"]
for filename in filenames:
    filename = filename.strip(filename[-4:])
    print(filename)`

the output is:

repor
downloads
success
folders

I expect that the 'T' letter of report don't be sliced, but I was surprised when I tried again and again.

2
  • @ti7 I don't think that's a good duplicate. The main question here is why strip works that way, and the confusion between stripping and slicing. Commented Sep 22 at 22:31
  • that's fair somewhat, though there are many interpretations - why, what's better, method nomenclature.. but we won't know unless @Nacer weighs in! they may further enjoy How slicing in Python works as a good read Commented Sep 23 at 1:54

2 Answers 2

6

What you need is simply

filename = filename[:-4]

or

filename = filename.removesuffix(".txt")

The .strip function works for individual characters, not strings. Using .strip(".txt") will remove every occurrence of ".", "t", and "x".

Sign up to request clarification or add additional context in comments.

Comments

3

.strip() removes each character from both ends of the string, not a complete substring, potentially leading to (or preventing) disaster!

>>> "texted_my_ex.txt".strip(".txt")
'exted_my_e'

The string methods .rstrip() and .lstrip() also exist to remove only from the right or left sides respectively, but will still consume characters until they run out of matches rather than matching all at once


Whenever you have paths or filenames (filenames are just short paths!), pathlib.Path is almost-certainly the most practical answer, as it provides additional methods for reaching different properties of the path, such as the extension (.suffix), making it relative to another path (.relative_to()), checking if it exists, renaming it, etc.

Specifically pathlib.Path(filename).stem should work for your and any inputs1

from pathlib import Path
filenames = ["report.txt", "downloads.txt", "success.txt", "folders.txt"]
for path in map(Path, filenames):
    print(f"{path.stem: <10} + {path.suffix} from {path}")
report     + .txt from report.txt
downloads  + .txt from downloads.txt
success    + .txt from success.txt
folders    + .txt from folders.txt

more features (note / is used to append, not +, and it will accept strings when adding more path to a Path instance)

>>> p = Path("report.txt")
>>> p.exists()
False
>>> Path("/root") / "some_very/long_path/middle_part" / p
PosixPath('/root/some_very/long_path/middle_part/report.txt')

Path will also handle multiple extensions in a nice way

>>> p = Path("somewhere/foo.tar.gz")
>>> p
PosixPath('somewhere/foo.tar.gz')
>>> p.suffix
'.gz'
>>> p.suffixes
['.tar', '.gz']

  1. take extra caution if you think you can have files with multiple extensions or dots in their path and need a very generic method .. unfortunately you may not be able to get away from doing some string parsing, though often asserting true things about files helps ensure correctness (such as enforcing a regex over input file names when users attempt to create or supply something silly)
>>> path_str = "base/title.d/myfile.first.second.txt2"
>>> path_str[:-4]                   # not very robust
'base/title.d/myfile.first.second.'
>>> path_str.split(".")[0]          # doesn't work for . in pathname
'base/title'
>>> p = Path(path_str)
>>> p.name                          # can get complete name
'myfile.first.second.txt2'
>>> p.suffix                        # only the final suffix
'.txt2'
>>> p.name.split('.')[0]            # potentially the most-correct
'myfile'

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.