在Python中对列表进行分区

3
我想了解如何修改列表的内容,具体来说就是通过os.listdir()返回的文件名。

这些文件名由若干重复的名称组成,然后是下划线、后缀和文件扩展名。我想把列表中的元素削减到文件名的第一部分,也就是在'_'前面的部分:

apple_d.jpg
apple_si.jpg
apple_sg.jpg

在列表中,'apple' 只是一个单独的条目。

我可以通过去除重复项并重新按字母顺序排列来完成此操作。

list(sorted(set(t)))

但是删除下划线及其后面的内容比较麻烦。我尝试通过 .rpartition("_")[0] 来实现这一点,但是对于列表来说似乎不起作用。因此,我想知道怎么做?

编辑:嗯,在这里不起作用。仍然会出现重复项,没有分割。

objects = os.listdir(dir)





    for object in objects:
        sorted(set(object.split('_', 1)[0]))
        cmds.menuItem(label = object, parent = "objectMenu")

(最后一个命令是Maya命令,用于填充选项菜单)。现在很累,所以我得稍后再处理。但非常感谢迄今为止的帮助。一定很快就能解决这个问题。


我猜你不是在寻找os.path.commonprefix...但它似乎接近你想要的,所以我在这里提一下。 - mgilson
@mgilson:commonprefix 适用于路径组件(因此由 os.sep 分隔),而不是文件名。 - Martijn Pieters
@MartijnPieters - 文档说它是按字符逐个处理的。我不明白为什么它不能用于文件名。 - mgilson
@mgilson:刚从啤酒节回来,我反而记错了commonprefix的工作原理... - Martijn Pieters
你是否期望文件名中只有一个下划线_?如果有多个下划线,应该在第一个还是最后一个下划线处进行分割? - Martijn Pieters
4个回答

6
使用 str.split()str.rsplit() ,并加上限制条件,然后选择首个元素:
filename.split('_', 1)[0]

.rsplit('_', 1) 可以在最后一个下划线处拆分,.split() 则在第一个下划线处拆分。选择适合您用例的方法。

这将为您提供该文件名中第一个或最后一个下划线之前的所有内容。

在使用集合推导式时,可以将其与从该集合返回的 sorted() 列表一起使用:

unique_prefixes = sorted({filename.split('_', 1)[0] for filename in os.listdir(somedir)})

对于Python 2.6及之前版本,由于没有集合推导式语法,以下使用set()的生成器表达式也可以实现:

unique_prefixes = sorted(set(filename.split('_', 1)[0] for filename in os.listdir(somedir)))

@mgilson:集合推导式比set()加生成器表达式稍微更加简洁。 - Martijn Pieters
@mgilson:集合推导式会消除重复项,列表推导式则不会。 - recursive
哦,我今天可能状态不太好。正在去重……谢谢。(我已经删除了上面愚蠢和不正确的评论)。 - mgilson
你是不是想用 rsplit?如果“前缀”包含下划线,这个方法不会奏效吧?当然,如果后缀包含下划线,rsplit也会出问题。而且如果前缀和后缀都包含下划线的话,我觉得你注定要失败了。 - jpmc26
@jpmc26:不,从问题中并不清楚;我理解后缀不包括任何下划线。如果前缀和后缀都包含下划线,则需要更复杂的规则来确定哪个是哪个。 - Martijn Pieters
1
我还在坚持,正在消化这些信息。作为 Python 新手,我的进度有点慢。 - user2407089

0

参考Martjin的答案,但我使用了rpartition而不是split,因为我特别想比较搜索字符串/字符最后一次出现之前的字符串的第一部分。

if x not in sorted({filename.rpartition(' - ')[0] for filename in os.listdir(somedir)}):
     some action...

0
根据我的理解,您试图直接在列表上调用 rpartition(可能类似于 os.listdir('path').rpartition('_')[0])。我认为,为了按照您的意图使用 rpartition,您需要将其应用于列表中的单个元素。列表推导式是最推荐的方法:
file_prefixes = [f.rpartition('_')[0] for f in os.listdir('path')]

将其转换为集合推导式,如Martijin Pieters建议的那样,将消除重复项:
file_prefixes = {f.rpartition('_')[0] for f in os.listdir('path')}

注意:这实际上应该等同于Martijin Pieters的答案,只是使用问题中提到的rpartition而不是rsplit。(基本上可以省去1参数。)

0
这对我有用,伙计们 -
labels = os.listdir(dir)




labels_processed=[]
for label in labels:
    labels_processed.append(label.split('_')[0])



labprocessed  = set(labels_processed)



for finallab in labprocessed:        
    cmds.menuItem(label = finallab, parent = "objectMenu")

干杯,
S Tozer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接