views:

62

answers:

5

I have a string as follows

CompilationStatistics_Compilation_StepList_Map_TimingUsage_ClockList_Clock_MinimumPeriod

What would be the simplest way to remove the first part (CompilationStatistics_) or the last part (_MiniumuPeriod)?

I think about using regular expression, but I expect there should a better way.

m = re.search("{.+}_{.+}", string)
m.group(2)
+1  A: 

If you know the size of the chunks you want to cut out, you can use Python's string slicing, like this:

s="CompilationStatistics_Compilation_StepList_Map_TimingUsage_ClockList_Clock_MinimumPeriod"
print s[22:-14]

Of course, there are other ways you can find the number you need, like using String.rindex() to find the place where the end chunk you want to cut off starts. For example:

print s[len("CompilationStatistics_"):s.rindex("_MinimumPeriod")]
ewall
+2  A: 

All but first:

s[s.find('_') + 1:]

All but last:

s[0:s.rfind('_')]

Without either:

s[s.find('_') + 1:s.rfind('_')]

find returns the first index of the string, and rfind returns the last. Then, we just use slice syntax.

Matthew Flaschen
Really have to disagree that this is the best answer. The question has nothing to do with finding the index of the underscore characters, so finding and slicing on them is a totally unnecessary step.
Jesse Dhillon
@Jesse, I could easily say the question has nothing to do with partitioning, and creating two intermediate lists is an unnecessary step. My code is shorter, faster (using `timeit`), and in my opinion clearer.
Matthew Flaschen
Well I guess that's why we have voting, to decide these subjective matters.
Jesse Dhillon
Well, voting means nothing more than accidental (or incidental) popularity. I prefer the r?partition methods because the .rfind method has a flaw (try to get “All but last” or “Without either” for `s` having no underscores.).
ΤΖΩΤΖΙΟΥ
+3  A: 

See the Python documentation for String methods, particularly partition and rpartition:

s = "CompilationStatistics_Compilation_StepList_Map_TimingUsage_ClockList_Clock_MinimumPeriod"
print s.partition('_')[2].rpartition('_')[0]

Result

Compilation_StepList_Map_TimingUsage_ClockList_Clock
Jesse Dhillon
Requires Python >=2.5, but this is the best answer if you're okay with that.
Zack
Your answer is the most correct one concerning corner cases (see my comment in Matthew Flaschen's answer), but the reasoning in your comments was not very sound, I'm sorry to say :)
ΤΖΩΤΖΙΟΥ
I thought that Matthew Iselin's answer was the most accurate, as the problem as I read it really is "I have a bunch of words joined with underscores, and I want all but the first and last of them," and his captures that elegantly. Others may have parsed the problem differently, but I stand by my reasoning on the other answer: `find()`-ing and adding 1 to an index before slicing on it is a solution that, if it were submitted anywhere I've ever worked, would have been rewritten.
Jesse Dhillon
Jesse, if the `.find()` solution worked correctly, it would be a matter of personal preference; however, it *doesn't* work correctly in all cases, and that's why it shouldn't be considered. Explaining why an answer is bad is sound reasoning IMO when you criticize that answer. Not explaining and/or relying on voting to justify you is *not* sound reasoning, again IMO. That's what I meant.
ΤΖΩΤΖΙΟΥ
I didn't know about the corner case in the `find` solution so I couldn't criticize it for that. And the remark about voting was not to say that mine was superior because it had more votes -- at the time I said it my solution was not the vote leader -- but to express that voting is one way to decide matters of opinion. I explained that I thought it was not the best answer because it was inelegant. The fact that it has a corner case that fails is an additional strike against it, and an objective -- thus better -- reason to disqualify it.
Jesse Dhillon
+3  A: 

'_'.join(s.split("_")[1:-1])?

Changing the splice numbers will change how much you get: removing the "-1" will only remove the first item, for example.

Matthew Iselin
A: 

Removing the first part is trivially down with split():

s.split("_", 1)[1] # Take the second part of the string, split into 2 pieces.
Oddthinking
That's exactly why the `.partition` and `.rpartition` methods were created.
ΤΖΩΤΖΙΟΥ
Wow, I learnt something new, thanks, @ΤΖΩΤΖΙΟΥ.
Oddthinking