More syntactic sugar please!

Despite enjoying my hacking experience in Python 🙂 there are a few rare constructs from other languages (mostly falling into the syntactic sugar category) that I am missing on occasion.

One such facility are Perl’s quote operators.

I hate typing too much 🙂 and Perl’s quote operator relieves me of typing all the quotes and commas normally needed to instantiate a list of words (see line 2).

  1 bbox33:mhr $ perl -e '
  2 > @list = qw(The quick brown fox jumps over the lazy dog);
  3 > print join('_', @list), "\\n";
  4 > '
  5 The_quick_brown_fox_jumps_over_the_lazy_dog

Conversely, initialising a list of strings in Python is messy since I have to type all that cruft (see line 10).

  6 bbox33:mhr $ python
  7 Python 2.5.1 Stackless 3.1b3 060516 (python-2.51:55546, May 24 2007, 08:50:09)
  8 [GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin
  9 Type "help", "copyright", "credits" or "license" for more information.
 10  >>> list = ['The', 'quick', 'brown', 'fox', 'jumps', 'over', 'the', 'lazy', 'dog']
 11  >>> print '_'.join(list)
 12 The_quick_brown_fox_jumps_over_the_lazy_dog

The best shortcut I have found so far is to type all the words needed in a long string and split it (see line 13).

 13  >>> list2 = 'The quick brown fox jumps over the lazy dog'.split()
 14  >>> print '_'.join(list2)
 15 The_quick_brown_fox_jumps_over_the_lazy_dog

Just wondering: did I miss some piece of Python magic here? Are there any other/better ways to initialise sequences of strings in Python?

13 thoughts on “More syntactic sugar please!

  1. so what’s wrong with the split?

    it’s short, it does the same thing as the qw, and you don’t need to learn another function

  2. This is the exact reason why I hate Perl.

    If I had never read Python before I could probably reasonably guess what “a b c”.split() did (as long as I had programmed in something higher than ASM in my life).

    Yet what the hell am I supposed to think qw does? Just because you like it doesn’t mean it needs to be added to the language. Perl is union of everyone’s pet feature and it sucks.

  3. I don’t really see what’s different between:

    qw(a string withOUT string delimiters is odd and ugly and strange!)

    and

    words = ‘A string with string delimiters is expected and comfortable’.split()

    And if making it only one line is your primary goal:

    Print ‘_’.join(‘A string with string delimiters is expected and comfortable’.split())

  4. Ah, the internet, the place where tolerance and understanding of other people’s tastes and opinions reign supreme 🙂

    Design (including the design of programming languages and code) is always a matter of taste.

    IMHO, the qw() operator is preferrable because it is more expressive of my intention. Remember, I wanted to initialise a sequence of strings and NOT split a long string.

    My Python shortcut is more of a hack than anything else. But, as they say, YMMV 🙂

  5. There is no better way in Python to build a list from words.

    You could, of course, write a function to do that: def qw(s): return s.split()

    That would asymptotically leave you at 2 more characters than Perl instead of 6.

    Or for something cool but inappropriate for most real world code,

    >>> class _QW(object):
    … def __init__(self, data=None):
    … if data is None: data = []
    … self.data = data
    … def __getattr__(self, name):
    … return _QW(self.data + [name])
    … def __call__(self):
    … return self.data

    >>> qw = _QW()

    (Hmmm, no preview and no hints on how to format this response. Probably the above will look horrible.)

    The result is

    >>> qw.The.quick.brown.fox.jumps.over.the.lazy.dog()

    [‘The’, ‘quick’, ‘brown’, ‘fox’, ‘jumps’, ‘over’, ‘the’, ‘lazy’, ‘dog’]

    and if I use “q” instead of qw then the asymptotic number of characters is the same as Perl’s.

    But please don’t do that.

    The most direct way to express your intention (“initialise a sequence of strings”) would be to use [“a”, “list”, “of”, “strings”]. That is direct and unambiguous in either language. What I think you’re actually searching for is a shorter yet still sufficiently unambiguous way to express your intent. In Perl the appropriate idiomatic way to do that is “qw(…)”. And in Python the idiom uses “.split()”. To a Python programmer the intent of string/split is almost as meaningful a way to make a list of strings from words as qw() is to Perl programmers.

  6. Indeed, I also discovered “separate words”.split() by myself, its just the natural thing for a pythonist, and when your exemple starts with “list = ” i think is pretty obvious you are creating a list.

    Ruby also implements this, here from the documentation %w( fred wilma barney betty great\ gazoo )

    That’s why Python is so much easier to learn, teach, use and keep using over the years

    Less magic is good for the soul, time to quote Ruby’s documentantion

  7. Sorry, is not from ruby’s documentation, is a quote from Matz:

    ” Actually, I didn’t make the claim that Ruby follows the principle of least surprise. Someone felt the design of Ruby follows that philosophy, so they started saying that. I didn’t bring that up, actually. ”

    I’d say, Python is the one that hides less surprises. Not that it doesn’t has them, like the print statement WTFery (although, it does exactly what you want 90% of the time).

  8. Pingback: links for 2007-07-04 « PaxoBlog

  9. How about:

    def qw(s): return s.split()

    >>> qw(‘The quick brown fox jumps over the lazy dog’)
    [‘The’, ‘quick’, ‘brown’, ‘fox’, ‘jumps’, ‘over’, ‘the’, ‘lazy’, ‘dog’]

Leave a reply to Jay Cancel reply