Python,字符串切片(从文件位置列表中获取文件名)

Python,字符串切片(从文件位置列表中获取文件名),python,string,Python,String,我正在尝试从文件位置列表中获取文件名。认为这涉及到线切割 我得出的结论是: L = ['C:\\Design\dw\file4.doc', 'C:\\light\PDF\downloads\list.doc', 'C:\\Design\Dq\file4g.doc', 'C:\\Design\Dq\file4r.doc', 'C:\\Design\Dq\file4k.doc', 'C:\\Design\Dq\ole.doc', 'C:\\GE\easy\file\os_references(9).

我正在尝试从文件位置列表中获取文件名。认为这涉及到线切割

我得出的结论是:

L = ['C:\\Design\dw\file4.doc',
'C:\\light\PDF\downloads\list.doc',
'C:\\Design\Dq\file4g.doc',
'C:\\Design\Dq\file4r.doc',
'C:\\Design\Dq\file4k.doc',
'C:\\Design\Dq\ole.doc',
'C:\\GE\easy\file\os_references(9).doc',
'C:\\mate\KLO\Market\BIZ\KP\who\Documents\REF.doc']

LL = []

for a in L:
    b = a.split('\')
    for c in b:
        if c.endswith('.doc'):
            c.replace('.doc', '')
            LL.append(c)

print LL
问题1:输出仍然包含“.doc”。为什么,我如何才能将其移除

问题2:获取文件名的更好方法是什么

谢谢

[file.split('\\')[-1].split('.')[0] for file in L]
在您的示例中,实际上没有进行任何切片。您正在拆分和替换。因为我们知道文件名和扩展名总是路径的最后一部分,所以我们可以在分割后使用负索引来访问它

一旦我们在句点上再次拆分,文件名将始终是第0个元素,因此我们可以抓住它并将其添加到列表中


编辑:我刚刚注意到,由于这是一个特殊的Python字符,因此此方法在包含\f的路径上会出现问题。

如果文件名中没有空格或其他符号,请尝试此方法

[re.findall('\w+.doc$', L) for x in L]
试着看一看

ntpath模块


第一件事替换方法返回带有替换值的字符串。它不会更改字符串。所以你需要这样做

c = c.replace('.doc', '')

第一个答案:replace返回字符串的一个副本,所以您不保存更改。 第二个答案:您需要获得几个路径的原始表示,因为像“\f”这样的组合被解释为utf-8字符。 因此,棘手的部分是将字符串格式化为其原始表示形式。为此,我使用了原始的 一旦我们有了这个函数,我们就可以很好地处理字符串了。 我使用re.split接受unix和dos格式的路径

>>> L = [re.split(r'[\/\\]', raw(path)) for path in L]
>>> L
[['C:', 'Design', 'dw', 'file4.doc'], ['C:', 'light', 'PDF', 'downloads', 'list.doc'], ['C:', 'Design', 'Dq', 'file4g.doc'], ['C:', 'Design', 'Dq', 'file4r.doc'], ['C:', 'Design', 'Dq', 'file4k.doc'], ['C:', 'Design', 'Dq', 'ole.doc'], ['C:', 'GE', 'easy', 'file', 'os_references(9).doc'], ['C:', 'mate', 'KLO', 'Market', 'BIZ', 'KP', 'who', 'Documents', 'REF.doc']]
现在L包含一个路径部分列表,因此您可以访问文件名及其扩展名,从而获得每个列表的最后一个元素

>>> L_names = [path_parts[-1] for path_parts in L if path_parts[-1].endswith('.doc')]
>>> L_names
['file4.doc', 'list.doc', 'file4g.doc', 'file4r.doc', 'file4k.doc', 'ole.doc', 'os_references(9).doc', 'REF.doc']

第一个要点是,您应该输入带有原始字符串r前缀的列表:

否则,将插入字符,在文件名中\…通常替换为单个字符

Python2有一个专门的子模块,只用于操作路径,它提供了预期的结果:

from os.path import basename, splitext                                          
print [splitext(basename(path))[0] for path in L]
请注意,路径和此脚本必须在使用相同路径分隔符/或\约定的系统上运行,通常情况下应该是这样的,因为路径通常在计算机上本地运行。您可以通过执行以下操作,使其专门用于任何操作系统上的Windows path:

from ntpath import basename, splitext 
然后,在任何机器上:

['file4', 'list', 'file4g', 'file4r', 'file4k', 'ole', 'os_references(9)', 'REF']

第一个问题的答案是字符串是不可变的,.replace不会就地修改字符串,即:

blaize@bolt ~ $ python 
>>> s = "foobar"
>>> s2 = s.replace("o", "x")
>>> print s
foobar
>>> print s2
fxxbar
我对第二个问题的答复如下:

# I use ntpath because I'm running on Linux.
# This way is more robust if you know you'll be dealing with Windows paths.
# An alternative is to import from os.path then linux filenames will work 
# in Linux and Windows paths will work in Windows.
from ntpath import basename, splitext

# Use r"" strings as people rightly point out.
# "\n" does not do what you think it might.
# See here: https://docs.python.org/2.0/ref/strings.html.
docs = [r'C:\Design\dw\file4.doc',
        r'C:\light\PDF\downloads\list.doc',
        r'C:\Design\Dq\file4g.doc',
        r'C:\Design\Dq\file4r.doc',
        r'C:\Design\Dq\file4k.doc',
        r'C:\Design\Dq\ole.doc',
        r'C:\Design/Dq/test1.doc',  # test a corner case
        r'\\some_unc_machine\Design/Dq/test2.doc',  # test a corner case
        r'C:\GE\easy\file\os_references(9).doc',
        r'C:\mate\KLO\Market\BIZ\KP\who\Documents\REF.doc']

# Please use meaningful variable names:
basenames = []

for doc_path in docs:

    # Please don't reinvent the wheel.
    # Use the builtin path handling functions.
    # File naming has a lot of exceptions and weird cases 
    # (particularly on Windows).
    file_name = basename(doc_path)
    file_basename, extension = splitext(file_name)
    if extension == ".doc":
        basenames.append(file_basename)

print basenames


祝你好运,伙计。Python是一种优秀的语言。

向下投票,因为Python有专门的标准工具用于此目的。这里的问题是获取字符串的原始表示形式,您在使用\f时有此错误。问题需要文件名,而你的答案没有提供文件名。你指出字符串输入的问题是对的。不过,我相信原始问题应该包含原始字符串,我知道海报主要是想知道如何获取没有扩展名的文件名。Downvoting,因为Python有专门的标准工具用于此目的。@EOL downvote,只有在答案错误时才使用。如果您使用专用工具提供答案,您将自动获得accept和UpVote,这将使其他答案获得downnot downvote。@AvinashRaj虽然我理解您的观点,但我确实认为不使用Python中的标准工具是错误的:这以一种非常不必要的方式模糊了代码的意图,这就强化了坏习惯。@IanAuld:Python在os中有文件路径处理工具。这里的path:basename和splitext以更清晰、更有效的方式为您完成任务。问题是什么?您得到了什么?看起来您正在使用Unix计算机分析Windows路径。我添加了一条警告:路径通常在给定的机器上有意义,因此当在与路径所在的机器具有相同路径分隔符约定的机器上运行时,此脚本可以工作。@AvinashRaj:您应该试试我的修订版,当前的解决方案。@ aviasajj:看起来你忘了使用原始的海报标记R,原来的海报可能忘记了,根据我的答案。你应该强烈考虑在你的路径串R '.…''之前添加R,以便使它们成为原始字符串:这可能是你想要的。您可以查看我的答案,以获得详细信息和有效、简单的解决方案!。文件名包含\路径分隔符,但代码包含/:这是您想要的吗?此外,您的加工路径是否与生产它们的机器在同一台机器上?如果两者之间的路径分隔符约定不同,则这一点很重要。感谢EOL提供的提示。上升+2这正是我在你之前两个小时的答案,所以我同意也许我的答案没有显示它目前有-3票!。EOL先生,不用担心。你的贡献得到广泛认可是的,EOL是对的。。我回答了最后一部分,然后重读了问题,意识到问题有第一部分。不知道你为什么要这么做
斯韦尔在奥勒被击落。堆栈溢出是易变的。它备份到0 fwiw。这不是非常有效或健壮:效率不高,因为从字符串末尾开始删除扩展名可以非常快速地完成,而替换不能完成,而健壮性不高,因为它会使用非常规文件名(如my.doc.doc)中断,这很重要,因为有简单而健壮的解决方案\w+与文件名中的9不匹配。在描述中给出,没有空格和符号。我还告诉你去看看ntpath。否决投票不是解决办法
# I use ntpath because I'm running on Linux.
# This way is more robust if you know you'll be dealing with Windows paths.
# An alternative is to import from os.path then linux filenames will work 
# in Linux and Windows paths will work in Windows.
from ntpath import basename, splitext

# Use r"" strings as people rightly point out.
# "\n" does not do what you think it might.
# See here: https://docs.python.org/2.0/ref/strings.html.
docs = [r'C:\Design\dw\file4.doc',
        r'C:\light\PDF\downloads\list.doc',
        r'C:\Design\Dq\file4g.doc',
        r'C:\Design\Dq\file4r.doc',
        r'C:\Design\Dq\file4k.doc',
        r'C:\Design\Dq\ole.doc',
        r'C:\Design/Dq/test1.doc',  # test a corner case
        r'\\some_unc_machine\Design/Dq/test2.doc',  # test a corner case
        r'C:\GE\easy\file\os_references(9).doc',
        r'C:\mate\KLO\Market\BIZ\KP\who\Documents\REF.doc']

# Please use meaningful variable names:
basenames = []

for doc_path in docs:

    # Please don't reinvent the wheel.
    # Use the builtin path handling functions.
    # File naming has a lot of exceptions and weird cases 
    # (particularly on Windows).
    file_name = basename(doc_path)
    file_basename, extension = splitext(file_name)
    if extension == ".doc":
        basenames.append(file_basename)

print basenames