如何解释Python 3.6 中的str.maketrans 函数?

新手上路,请多包涵

我目前正在参加 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。然后字符键将被转换为序数。

它说它只能将整数或长度为 1 的字符串中的字符更改为其他整数或字符串(您想要的任何长度)。但我相信我有三个论点,而不是一个。

如果有两个参数,它们必须是等长的字符串,并且在生成的字典中,x 中的每个字符将映射到 y 中相同位置的字符。如果有第三个参数,它必须是一个字符串,其字符将在结果中映射到 None 。

我有三个参数 ('', '', '0123456789') 。我认为 x y 第一个 '' '' 我有第三个参数,它是一个字符串 '0123456789' ,但我不明白映射到 'None' 意味着什么。

原文由 Dennis 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 737
2 个回答

str.maketrans 构建一个转换表,它是整数或字符到整数、字符串或 None 的映射。可以把它想象成一个字典,其中的键代表输入字符串中的字符,它们映射的值代表输出字符串中的字符。

我们通过字符串来翻译和替换在映射中作为键出现的所有内容,无论其在映射中的值是什么,或者如果该值为 None 则将其删除。

您可以使用一个、两个或三个参数构建一个转换表(我认为这可能会让您感到困惑)。有一个论点:

 str.maketrans({'a': 'b', 'c': None})

您为函数提供一个遵循转换表规则的映射,它返回该映射的等效表。映射到 None 的东西被删除

有两个参数:

 str.maketrans('abc', 'xyz')

你给它两个字符串。第一个字符串中的每个字符都被第二个字符串中该索引处的字符替换。 So 'a' maps to 'x' , 'b' to 'y' , and 'c' to 'z' .

您正在使用的带有三个参数的字符串与两个参数的工作方式相同,但具有第三个字符串。

 str.maketrans('abc', 'xyz', 'hij')

这与双参数版本相同,只是删除了第三个字符串中的字符,就好像它们被映射到 None 。所以你的表说“不要替换任何东西,但删除出现在这个字符串中的字符”。

原文由 Patrick Haugh 发布,翻译遵循 CC BY-SA 4.0 许可协议

来自 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')

If you apply this to your string now, it’ll also capitalize 'athens' to 'Athens' due to the extra 'a', 'A' we’ve provided to maketrans 。不是最好的翻译,但足以掌握功能。

str_obj.translate 然后将在该字典中为 str_obj 中的每个字符执行查找—将其值替换为在映射中找到的值。如果它没有在映射中找到它,它会保持原样,如果它是 None 它会删除它。这在 str.translate 的文档中说明

当由 Unicode 序号(整数)索引时,表对象可以执行以下任何操作:返回 Unicode 序号或字符串,将字符映射到一个或多个其他字符; _return None ,从返回字符串中删除字符_;或引发 LookupError 异常,将字符映射到自身。

(强调我的)

原文由 Dimitris Fasarakis Hilliard 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题