user2407089
user2407089

Reputation: 59

Partitioning a list in Python

I would like to find out how to modify the contents of a list, specifically filenames which have been returned by os.listdir().

The filenames consist of a number of duplicate names followed by an underscore, then a suffix, and then the file extension. I'm trying to cut the elements in the list down to just the first part of the filename, before the '_', so:

apple_d.jpg
apple_si.jpg
apple_sg.jpg

becomes just a single entry in the list, 'apple'.

I'm able to get rid of duplicates and re-alphabetise with

list(sorted(set(t)))

but getting rid of everything from the underscore onwards is proving tricky. I tried to do this via .rpartition("_")[0]. but that apparently doesn't work for lists. So I'm wondering how to go about this?

edit: well, not working here. Still getting duplicates and no splitting.

objects = os.listdir(dir)





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

(The last command is a maya command, which populates an option menu). Very tired now so I'll have to take this up later. But thanks so much for the help to date. Sure to get this soon.

Upvotes: 3

Views: 2229

Answers (4)

jpmc26
jpmc26

Reputation: 29874

From my understanding of the question, you tried to call rpartition directly on the list (perhaps like os.listdir('path').rpartition('_')[0]). I believe that to use rpartition in the manner you intend, you need to apply it to individual elements of the list. A list comprehension is the most recommended way to do this:

file_prefixes = [f.rpartition('_')[0] for f in os.listdir('path')]

Turning it into a set comprehension as Martijin Pieters suggests will eliminate duplicates:

file_prefixes = {f.rpartition('_')[0] for f in os.listdir('path')}

Note: This should actually be equivalent to Martijin Pieters' answer, just using rpartition as mentioned in the question instead of rsplit. (Basically saves you the 1 parameter.)

Upvotes: 0

Shirish Dubey
Shirish Dubey

Reputation: 31

Referred answer by Martjin but instead of using split I used rpartition as was specifically interested in comparing 1st part of the string before the last occurrence of searched string/character -

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

Upvotes: 0

user2407089
user2407089

Reputation: 59

This worked for me guys-

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

Cheers,

S Tozer

Upvotes: 0

Martijn Pieters
Martijn Pieters

Reputation: 1121972

Use str.split() or str.rsplit() with a limit, then select the first element:

filename.split('_', 1)[0]

.rsplit('_', 1) will split on the last underscore, .split() on the first. Pick the one that fits your usecase best.

This gives you everything before the first or last underscore for that filename.

Using this in a set comprehension, with sorted() returning a list from that set:

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

For Python 2.6 and earlier, where you don't yet have a set comprehension syntax, the following generator expression with set() would work too:

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

Upvotes: 6

Related Questions