Python showboating

Some javascript sends a string like this: a_1_b_2_c_3, so here’s how I parse it:

>>> s
'a_1_b_2_c_3'
>>> a, b, c = [int(x) for x in s.split('_')[1::2]]
>>> a, b, c
(1, 2, 3)

More seriously, this guy’s post on why zip is the same as unzip blew my mind.

8 thoughts on “Python showboating

  1. Python is sweet.

    Here's another variant:

    >>> dict(zip([x for x in s.split('_')[0::2]], [int(x) for x in s.split('_')[1::2]]))
    {'a': 1, 'c': 3, 'b': 2}

  2. Or if you wanted to make this really ugly but minimize memory required:

    >>> from itertools import islice, izip
    >>> parts = s.split('_')
    >>> seq1 = islice(parts, 0, None, 2)
    >>> seq2 = islice(parts, 1, None, 2)
    >>> dict(izip(seq1, seq2))

  3. Here's some more general code from pyfdate
    http://www.ferg.org/pyfdate

    def numsplit(s):
    “””
    split a string into its numeric parts and return
    a list containing the numeric parts converted to ints.

    This function can be used to parse a string containing
    an ISO datetime.

    >>> from pyfdate import *
    >>> numsplit(“2007_10_09”)
    [2007, 10, 9]
    >>> numsplit(“2007-10-09T23:45:59”)
    [2007, 10, 9, 23, 45, 59]
    >>> numsplit(“2007/10/09 23.45.59”)
    [2007, 10, 9, 23, 45, 59]
    “””
    s = list(s)
    for i in range(len(s)):
    if not s[i] in “0123456789”: s[i] = ” “
    return [int(x) for x in “”.join(s).split()]

  4. If you think that is neat than this will pop your skull. Let's make a dictionary out of the name:integer pairs.

    s = 'a_1_b_2_c_3'
    parts = iter(s.split('_'))
    d = dict(zip(parts, (int(x) for x in parts)))

    The second arg to zip needs to be a generator (parens) instead of a list comprehension (square brackets). The iterator will be consumed alternately between the first and second args to zip. You end up with a list of names and their integer values.

  5. Fair warning: I wouldn't write that in production code because it places an unnecessary burden on the next reader (which would also be me). You need to notice the “iter()” on the line above to be able to read the line that consumes it. Unless you know you will be eating arbitrarily large strings this kind of subtlety isn't needed. If you do need it it should be flagged with a comment.

  6. Jack, that iter trick is really neat! I'm going to need to remember that one.

    I agree with your remarks about avoiding fancypants stuff like that in
    production code. However, when I do write fairly cryptic stuff, I
    tend to write a big docstring with doctests. Seeing provably-correct
    examples is a quick way (for me, anyway) to understand what the heck
    some code does.

    Matt

Comments are closed.