Подтвердить что ты не робот

Как объяснить функцию 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'.

4b9b3361

Ответ 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' пустыми строками, удалив его.