1

Today, I saw a presentation from pyData 2017 where the presenter used python's splat operator *. Imagine my surprise as I saw it as a pointer until he used the method. I thought Python's splat operator was something like an ellipsis ... No? A google search turned up nothing for me. Did they change it at some point or was it always *? If they did change it, why? Is there an implementation difference and/or speed difference if they changed it?

Edit: "unpacking argument lists" for the angry commenters.

David Frick
  • 641
  • 1
  • 9
  • 25

1 Answers1

5

No, Python's unpacking operator (sometimes called "splat" or "spread") never used the ... ellipsis symbol. Python has an .../Ellipsis literal value, but it's only used as a singleton constant for expressing multidimensional ranges in libraries like NumPy. It has no intrinsic behavior and is not syntactically valid in locations where you would use the * unpacking operator.

We can see that the change log for Python 2.0 (released in 2000) describes the new functionality of being able to use the * unpacking operator to call a function, but using the * asterisk character to define a variadic function (sometimes called using "rest parameters") is older than that.

A new syntax makes it more convenient to call a given function with a tuple of arguments and/or a dictionary of keyword arguments. In Python 1.5 and earlier, you’d use the apply() built-in function: apply(f, args, kw) calls the function f() with the argument tuple args and the keyword arguments in the dictionary kw. apply() is the same in 2.0, but thanks to a patch from Greg Ewing, f(*args, **kw)is a shorter and clearer way to achieve the same effect. This syntax is symmetrical with the syntax for defining functions.

The source code for Python 1.0.1 (released in 1994) is still available from the Python website, and we can look at some of their examples to confirm that the use of the * asterisk character for variadic function definitions existed even then. From Demo/sockets/gopher.py:

# Browser main command, has default arguments
def browser(*args):
        selector = DEF_SELECTOR
        host = DEF_HOST
        port = DEF_PORT
        n = len(args)
        if n > 0 and args[0]:
                selector = args[0]
Jeremy
  • 1
  • 85
  • 340
  • 366
  • Nit: `...` is not an operator; it's just a value. It's isomorphic to `None` (both are singleton values of a specific type). – chepner Apr 15 '19 at 23:04
  • @chepner Hmm, true... would it be correct to call it a keyword, even though it doesn't satisfy the normal identifier constraints? – Jeremy Apr 15 '19 at 23:06
  • 2
    Hm. I would have called it a literal, just as `1`, `2`, etc are `int` literals without being keywords or identifiers. Oddly, the [docs on lexical analysis](https://docs.python.org/3/reference/lexical_analysis.html) doesn't mention it; I guess it's not a single token but the [grammar](https://docs.python.org/3/reference/grammar.html?highlight=grammar) specifically mentions `...` as being "tokenized" as `Ellipsis`. The grammar also mentions `...` as an *atom*, the same as the other literals. – chepner Apr 16 '19 at 00:40