34
\$\begingroup\$

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?

\$\endgroup\$
1
  • 3
    \$\begingroup\$ 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. \$\endgroup\$ Aug 21, 2012 at 7:34

3 Answers 3

19
\$\begingroup\$
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
\$\endgroup\$
1
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ Aug 10, 2014 at 18:05
7
\$\begingroup\$

You can concatenate an array with your default value.

track, num_tracks = (track_info.split('/', 1) + [None])[:2]
\$\endgroup\$
6
\$\begingroup\$

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('/'))
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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