首页 文章

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

提问于
浏览
19

我目前正在参加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)

值得庆幸的是,我找到了另一种方式使用某人's assistance. However, I'我不确定它是如何工作的 . 有人可以向我解释 str.maketrans 函数,以及引号中的前两个空白参数是什么?我的想法是它说:对于文件名中的前两个字符,删除任何数字(0到9) . 那是对的吗?例如,在 "48athens" 中,如果它们是0到9之间的数字,则删除前两个字符(4和8) .

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()

My Understanding of the Documentation:

static str.maketrans(x [,y [,z]])此静态方法返回可用于str.translate()的转换表 .

它说传递给 str.maketrans 的参数以及实际的函数 str.maketrans 会产生一个表格,但是,我不确定括号的含义 .

如果只有一个参数,则它必须是将Unicode序数(整数)或字符(长度为1的字符串)映射到Unicode序数,字符串(任意长度)或无的字典 . 然后将字符键转换为序数 .

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

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

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

4 回答

  • 4

    str.maketrans 构建转换表,它是整数或字符到整数,字符串或 None 的映射 . 把它想象成一本字典 . 我们通过字符串来翻译并替换映射中显示为关键字的所有内容,无论其在 Map 中的值是什么 .

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

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

    您为函数提供遵循转换表规则的映射,并返回该映射的等效表 . 映射到 None 的内容将被删除

    有两个参数:

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

    你给它两个字符串 . 第一个字符串中的每个字符都被第二个字符串中该索引处的字符替换 . 所以 'a' 映射到 'x''b''y''c''z' .

    你正在使用的那个,有三个参数,与两个参数的作用相同,但有第三个字符串 .

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

    这与两个参数版本相同,只是删除了第三个字符串中的字符,就像它们被映射到 None 一样 . 所以你的 table 说"Don't replace anything, but remove the characters that show up in this string" .

  • -3

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

    如果你现在将它应用于你的字符串,由于我们提供给 maketrans 的额外 'a', 'A' ,它也会将 'athens' 大写为 'Athens' . 不是最好的翻译,但足以掌握功能 .

    然后, str_obj.translate 将对此字典中的每个字符执行查找,以便将 str_obj 中的每个字符替换为映射中找到的值 . 如果它没有在映射中找到它,它会保持原样,如果它是 None 它将其删除 . 这在documentation for str.translate中说明:

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

    (强调我的)

  • 0
    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()
    
  • 27

    你可以简单地使用:

    str.replace('num', '')
    

    这将取代 num'1234567890' 中的任何数字与空字符串,这将删除它 .

相关问题