Как объяснить функцию str.maketrans в Python 3.6?
В настоящее время я участвую в курсе Udacity, который инструктирует студентов о программировании с использованием Python. В одном из проектов ученики переименовывают файлы фотографий (удаляют любые номера в имени) в каталоге, чтобы файлы располагались в алфавитном порядке, после чего будет прописано секретное сообщение. Например, если имя файла "48athens"
, программа пытается удалить номера, оставив только "athens"
в качестве имени файла.
Я использую Python 3.6, в то время как преподаватель курса использует Python 2.7. Вероятно, я должен использовать Python 2.7, чтобы упростить процесс обучения. Однако на данный момент я буду продолжать использовать Python 3.6.
Способ, которым инструктор имеет переименованные файлы, использует функцию .translate
, которая принимает два аргумента в Python 2.x, в то время как Python 3.x принимает только один аргумент. Он удаляет любые числа (от 0 до 9) из имен файлов.
import os
def rename_files(): #Obtain the file names from a folder.
file_list = os.listdir(r"C:\Users\Dennis\Desktop\OOP\prank\prank")
print (file_list)
saved_path = os.getcwd()
os.chdir(r"C:\Users\Dennis\Desktop\OOP\prank\prank")
for file_name in file_list: #Rename the files inside of the folder.
os.rename(file_name, file_name.translate(None, "0123456789"))
os.chdir(saved_path)
rename_files()
Однако это не работает в Python 3.x, поскольку он говорит, что:
TypeError: translate() takes exactly one argument (2 given)
К счастью, я нашел другой способ использования помощи. Тем не менее, я не совсем уверен, как это работает. Может ли кто-нибудь объяснить мне функцию str.maketrans
и каковы первые два пустых аргумента в кавычках? Моя мысль заключается в том, что он говорит: для первых двух символов в имени файла удалите любые числа (от 0 до 9). Это верно? Например, в "48athens"
удалите первые два символа (4 и 8), если они являются цифрами от 0 до 9.
import os
def rename_files(): #Obtain the file names from a folder.
file_list = os.listdir(r"C:\Users\Dennis\Desktop\OOP\prank\prank")
print (file_list)
saved_path = os.getcwd()
os.chdir(r"C:\Users\Dennis\Desktop\OOP\prank\prank")
for file_name in file_list: #Rename the files inside of the folder.
os.rename(file_name, file_name.translate(str.maketrans('','','0123456789')))
os.chdir(saved_path)
rename_files()
Мое понимание документации:
static str.maketrans(x[, y[, z]])
Этот статический метод возвращает таблицу перевода, используемую для str.translate()
.
Говоря, что аргументы, переданные str.maketrans
, вместе с фактической функцией str.maketrans
, создадут таблицу, в которой говорится: "Если этот символ появляется, замените его на этот символ". Тем не менее, я не уверен, для чего нужны скобки.
Если есть только один аргумент, это должен быть словарь, отображающий Unicode ординалы (целые числа) или символы (строки длиной 1) в Unicode ординалы, строки (произвольной длины) или None. Символьные клавиши будут затем преобразуются в ординалы.
Он говорит, что он может изменять только целые числа или символы в строках длиной один, другим целым числам или строкам (любой длины, которую вы хотите). Но я считаю, что у меня есть три аргумента, а не один.
Если есть два аргумента, они должны быть строками равной длины и в результирующем словаре каждый символ в x будет отображен на символ в том же положении в y. Если есть третий аргумент, должна быть строкой, символы которой будут отображаться в None в результат.
У меня есть три аргумента ('', '', '0123456789')
. Я думаю, что x
является первым ''
, а y
является вторым ''
. У меня есть третий аргумент, который представляет собой строку '0123456789'
, но я не понимаю, что значит быть сопоставленным с 'None'
.
Ответы
Ответ 1
str.maketrans
строит таблицу переводов, которая представляет собой отображение целых чисел или символов в целые числа, строки или None
. Подумайте об этом, как о словаре. Мы переходим через строку для перевода и замены всего, что отображается в качестве ключа в сопоставлении, независимо от его значения на карте.
Вы можете построить таблицу трансляции с одним, двумя, тремя аргументами (я думаю, что это может вас смутить). С одним аргументом:
str.maketrans({'a': 'b', 'c': None})
Вы даете функции сопоставление, которое следует правилам для таблиц перевода, и возвращает эквивалентную таблицу для этого сопоставления. Вещи, которые отображаются на None
, удаляются
С двумя аргументами:
str.maketrans('abc', 'xyz')
Вы даете ему две строки. Каждый символ в первой строке заменяется символом этого индекса во второй строке. Итак, 'a'
отображается на 'x'
, 'b'
до 'y'
и 'c'
до 'z'
.
Тот, который вы используете, с тремя аргументами, работает так же, как два аргумента, но имеет третью строку.
str.maketrans('abc', 'xyz', 'hij')
Это то же самое, что и две версии аргумента, за исключением того, что символы из третьей строки удаляются, как если бы они были сопоставлены с None
. Поэтому в вашей таблице говорится: "Не заменяйте ничего, но удаляйте символы, которые отображаются в этой строке".
Ответ 2
Из документации по str.maketrans
:
Если есть третий аргумент, он должен быть строкой, символы которой будут отображаться в None
в результате.
Это то, что делает str.maketrans
; он принимает каждый элемент в третьем аргументе и создает карту (словарь Python), которая отображает каждое порядковое значение символов в строке на None
:
>>> str.maketrans('', '', '0123456789')
{48: None,
49: None,
50: None,
51: None,
52: None,
53: None,
54: None,
55: None,
56: None,
57: None}
Если дополнительные значения существуют как первый и второй аргументы, они добавляются к этому сопоставлению в качестве дополнительных символов для перевода (поэтому автор выбрал ''
и ''
; он не хочет, чтобы дополнительные символы были переведено):
>>> str.maketrans('a', 'A', '0123456789')
{48: None,
49: None,
50: None,
51: None,
52: None,
53: None,
54: None,
55: None,
56: None,
57: None,
97: 65} # map ord('a') to ord('A')
Если вы примените это к своей строке сейчас, она также будет использовать значение 'athens'
в 'athens'
из-за дополнительного 'a', 'A'
, который мы предоставили maketrans
. Не самый лучший из переводов, но достаточно, чтобы понять функциональность.
str_obj.translate
затем выполнит поиск по этому словарю для каждого символа в str_obj
, заменив его значения на найденные в отображении. Если он не находит его внутри отображения, он оставляет его как есть, если он None
удаляет его. Это указано в документации для str.translate
:
При индексировании по порядковому номеру Unicode (целому числу) объект таблицы может выполнять любое из следующих действий: вернуть порядковый номер Unicode или строку для сопоставления символа одному или нескольким другим символам; return None
, чтобы удалить символ из возвращаемой строки; или поднять исключение LookupError
, чтобы сопоставить символ себе.
(Акцент мой)
Ответ 3
import string
import os
# Required to call maketrans function.
#trantab = maketrans()
def rename_files():
x=os.listdir(r'C:\Users\user\Desktop\prank')
print (x)
path=os.getcwd()
print("path is"+path)
os.chdir(r'C:\Users\user\Desktop\prank')
for file in x:
os.rename(file,file.translate(file.maketrans('','','0123456789')))
rename_files()
Ответ 4
Вы можете просто использовать:
str.replace('num', '')
это заменит num
на любое число в '1234567890'
пустыми строками, удалив его.