Let's say I want to parse audio track information into two variables like this:

  • '2/15' -> track = 2, num_tracks = 15
  • '7' -> track = 7, num_tracks = None

What's an elegant way to do this in Python? For example:

track, num_tracks = track_info.split('/')

This works for the first format, but not for the second, raising ValueError: need more than 1 value to unpack. So I came up with this:

try:
    track, num_tracks = track_info.split('/', 1)
except:
    track, num_tracks = track_info, None

How can this be more elegant or better?

migrated from programmers.stackexchange.com Aug 21 '12 at 14:59

This question came from our site for professionals, academics, and students working within the systems development life cycle.

  • 2
    Don't use a bare except though; catch specific exceptions only. You'd be amazed how many bugs could be masked by blanket except statements. – Martijn Pieters Aug 21 '12 at 7:34
up vote 16 down vote accepted
try:
    track, num_tracks = track_info.split('/', 1)
except:
    track, num_tracks = track_info, None

Honestly, this is not a terrible solution. But you should almost never use except:; you should catch a specific exception.

Here is another way:

tracks, _, num_tracks = text.partition('/')
return int(tracks), int(num_tracks) if num_tracks else None
  • 1
    I would remove the parameter maxsplit=1 to split. If the text contains more than one '/' it is a good thing to get an error. – Emanuele Paolini Aug 10 '14 at 18:05

This may be overly generic, but could be reused. It "pads" a sequence by making it long enough to fit the requested length, adding as many repetitions as necessary of a given padding item.

def right_pad(length, seq, padding_item=None):
    missing_items = length - len(seq)
    return seq + missing_items * [ padding_item]

If the sequence is long enough already, nothing will be added. So the idea is to extend to 2 elements with None, if the second is not present:

track, num_tracks = right_pad(2, track_info.split('/'))

You can concatenate an array with your default value.

track, num_tracks = (track_info.split('/', 1) + [None])[:2]

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.