a flattening operator?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • gangesmaster

    #1

    a flattening operator?

    as we all know, * (asterisk) can be used to "inline" or "flatten" a
    tuple into an argument list, i.e.:

    def f(a, b, c):
    ...
    x = (1,2,3)
    f(*x)

    so... mainly for symmetry's sake, why not make a "flattening " operator
    that also works outside the context of function calls? for example:

    a = (1,2,3)
    b = (4,5)
    c = (*a, *b) # ==> (1,2,3,4,5)

    yeah, a + b would also give you the same result, but it could be used
    like format-strings, for "templating " tuples, i.e.

    c = (*a, 7, 8, *b)

    i used to have a concrete use-case for this feature some time ago, but
    i can't recall it now. sorry. still, the main argument is symmetry:
    it's a syntactic sugar, but it can be useful sometimes, so why limit it
    to function calls only?

    allowing it to be a generic operator would make things like this
    possible:

    f(*args, 7) # an implied last argument, 7, is always passed to the
    function

    today you have to do

    f(*(args + (7,)))

    which is quite ugly.

    and if you have to sequences, one being a list and the other being a
    tuple, e.g.
    x = [1,2]
    y = (3,4)

    you can't just x+y them. in order to concat them you'd have to use
    "casting" like
    f(*(tuple(x) + y))

    instead of
    f(*x, *y)

    isn't the latter more elegant?

    just an idea. i'm sure people could come up with more creative
    use-cases of a standard "flattening operator". but even without the
    creative use cases -- isn't symmetry strong enough an argument? why are
    function calls more important than regular expressions?

    and the zen proves my point:
    (*) Beautiful is better than ugly --> f(*(args + (7,))) is ugly
    (*) Flat is better than nested --> less parenthesis
    (*) Sparse is better than dense --> less noise
    (*) Readability counts --> again, less noise
    (*) Special cases aren't special enough to break the rules --> then why
    are function calls so special?

    the flattening operator would work on any sequence (having __iter__ or
    __next__), not just tuples and lists. one very useful feature i can
    thik of is "expanding" generators, i.e.:

    print xrange(10) # ==> xrange(10)
    print *xrange(10) # ==> (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

    i mean, python already supports this half-way:[color=blue][color=green][color=darkred]
    >>> def f(*args):[/color][/color][/color]
    .... print args
    ....[color=blue][color=green][color=darkred]
    >>> f(*xrange(10))[/color][/color][/color]
    (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

    so... why can't i just do "print *xrange(10)" directly? defining a
    function just to expand a generator? well, i could use
    "list(xrange(10 ))" to expand it, but it's less intuitive. the other way
    is list-comprehension, [x for x in xrange(10)], but isn't *xrange(10)
    more to-the-point?

    also, "There should be one-- and preferably only one --obvious way to
    do it"... so which one?
    (*) list(xrange(10) )
    (*) [x for x in xrange(10)]
    (*) [].extend(xrange( 10))
    (*) f(*xrange(10))

    they all expand generators, but which is the preferable way?

    and imagine this:

    f(*xrange(10), 7)

    this time you can't do *(xrange(10) + (7,)) as generators do not
    support addition... you'd have to do *(tuple(xrange( 10)) + (7,)) which
    is getting quite long already.

    so as you can see, there are many inconsistencies between function-call
    expressions and regular expressions, that impose artificial limitations
    on the language. after all, the code is already in there to support
    function-call expressions. all it takes is adding support for regular
    exoressions.

    what do you think? should i bring it up to python-dev?


    -tomer

  • Lawrence D'Oliveiro

    #2
    Re: a flattening operator?

    In article <1145317740.898 240.172830@i39g 2000cwa.googleg roups.com>,
    "gangesmast er" <tomerfiliba@gm ail.com> wrote:
    [color=blue]
    >as we all know, * (asterisk) can be used to "inline" or "flatten" a
    >tuple into an argument list, i.e.:
    >
    >def f(a, b, c):
    > ...
    >x = (1,2,3)
    >f(*x)
    >
    >so... mainly for symmetry's sake, why not make a "flattening " operator
    >that also works outside the context of function calls?[/color]

    def flatten(*a) :
    return a

    Comment

    • Michael Tobis

      #3
      Re: a flattening operator?

      I think by "regular expressions" you mean "expression s". "regular
      expressions" are what you get from "import re" .

      mt

      Comment

      Working...