How to replace file extensions?

Asked

Viewed 69 times

0

I am learning python in Oursera, and came across the following exercise. My question refers to how to change string extensions .hpp to .h inside the list comprehension:

filenames = ["program.c", "stdio.hpp", "sample.hpp", "a.out", "math.hpp", "hpp.out"]

newfilenames = [ i for i in filenames if _____] 

print(newfilenames) 
# Should be ["program.c", "stdio.h", "sample.h", "a.out", "math.h", "hpp.out"]

inserir a descrição da imagem aqui

2 answers

0

If you want to work with filenames, you could even manipulate the strings directly, as indicates the another answer.

But you also have the option to use a specific module for such, such as pathlib. So you can check the file extension and change it accordingly:

from pathlib import Path

def change_extension(nome_arq):
    path = Path(nome_arq)
    # se a extensão é .hpp, troca por .h e retorna o novo nome
    if path.suffix == '.hpp':
        return path.with_suffix('.h').name
    # senão, retorna o nome sem modificação
    return nome_arq

filenames = ["program.c", "stdio.hpp", "sample.hpp", "a.out", "math.hpp", "hpp.out"]

newfilenames = [ change_extension(name) for name in filenames ] 
print(newfilenames) # ["program.c", "stdio.h", "sample.h", "a.out", "math.h", "hpp.out"]

# outra opção: aplicar a função a todos os elementos usando map
newfilenames = list(map(change_extension, filenames))

This way it seems simpler to me than to slice strings and swap pieces of it.

And the function is easily extensible, because if you need to change more extensions, you can for example have a dictionary that maps before and after:

from pathlib import Path

def change_extension(nome_arq, substituicoes):
    path = Path(nome_arq)
    if path.suffix in substituicoes: # se a extensão deve ser substituída
        return path.with_suffix(substituicoes[path.suffix]).name
    return nome_arq

substituicoes = {
    '.hpp': '.h', # trocar .hpp por .h
    '.cpp': '.c', # trocar .cpp por .c
    '.out': ''    # extensão .out é removida
}
filenames = ["program.cpp", "stdio.hpp", "sample.hpp", "a.out", "math.hpp", "hpp.out", "abc.txt", "def.c"]
newfilenames = [ change_extension(name, substituicoes) for name in filenames ] 
print(newfilenames) # ['program.c', 'stdio.h', 'sample.h', 'a', 'math.h', 'hpp', 'abc.txt', 'def.c']

0

Since you need to replace one extension with another you should work with string slicing.

Note that the extensions you need to replace have 4 characters who are; .hpp. this way you need to go through the list that contains all the strings, checking if any of them - which I will call it i - has the length equal to .hpp, that is, if the respective index string is sliced -4 until the end forms the extension .hpp. In other words...

i[-4:] == '.hpp'

If any of these extensions are .hpp, we should replace them with .h. What we achieve with a concatenation between the string part WITHOUT the extension with the new extension .h, that is to say:

i[:-4] + '.h'

Using this logic together with List Comprehension, we can implement the following code:

filenames = ["program.c", "stdio.hpp", "sample.hpp", "a.out", "math.hpp", "hpp.out"]
newfilenames = [i[:-4] + '.h' if i[-4:] == '.hpp' else i for i in filenames]

print(newfilenames)

In this way, we obtain as output, the following result:

['program.c', 'stdio.h', 'sample.h', 'a.out', 'math.h', 'hpp.out']

Another agile way to resolve this issue is by calling the function replace. This way the code would be:

filenames = ["program.c", "stdio.hpp", "sample.hpp", "a.out", "math.hpp", "hpp.out"]
newfilenames = [i.replace('.hpp', '.h') for i in filenames]

print(newfilenames)

In this code, the for block goes through the list filename, replacing all substrings .hpp for .h.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.