Pythonic/idiomatic?

Discussion in 'Python' started by Seebs, Nov 8, 2010.

  1. Seebs

    Seebs Guest

    I have an existing hunk of Makefile code:
    CPPFLAGS = "$(filter -D* -I* -i* -U*,$(TARGET_CFLAGS))"
    For those not familiar with GNU makeisms, this means "assemble a string
    which consists of all the words in $(TARGET_CFLAGS) which start with one
    of -D, -I, -i, or -U". So if you give it
    foo -Ibar baz
    it'll say
    -Ibar

    I have a similar situation in a Python context, and I am wondering
    whether this is an idiomatic spelling:

    ' '.join([x for x in target_cflags.split() if re.match('^-[DIiU]', x)])

    This appears to do the same thing, but is it an idiomatic use of list
    comprehensions, or should I be breaking it out into more bits?

    You will note that of course, I have carefully made it a one-liner so I
    don't have to worry about indentation*.

    -s
    [*] Kidding, I just thought this seemed like a pretty clear expression.
    --
    Copyright 2010, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
    I am not speaking for my employer, although they do rent some of my opinions.
    Seebs, Nov 8, 2010
    #1
    1. Advertising

  2. On Mon, Nov 8, 2010 at 6:32 PM, Seebs <> wrote:
    > I have an existing hunk of Makefile code:
    >        CPPFLAGS = "$(filter -D* -I* -i* -U*,$(TARGET_CFLAGS))"
    > For those not familiar with GNU makeisms, this means "assemble a string
    > which consists of all the words in $(TARGET_CFLAGS) which start with one
    > of -D, -I, -i, or -U".  So if you give it
    >        foo -Ibar baz
    > it'll say
    >        -Ibar
    >
    > I have a similar situation in a Python context, and I am wondering
    > whether this is an idiomatic spelling:
    >
    >        ' '.join([x for x in target_cflags.split() if re.match('^-[DIiU]', x)])
    >
    > This appears to do the same thing, but is it an idiomatic use of list
    > comprehensions, or should I be breaking it out into more bits?
    >
    > You will note that of course, I have carefully made it a one-liner so I
    > don't have to worry about indentation*.
    >
    > -s
    > [*] Kidding, I just thought this seemed like a pretty clear expression.


    I believe this is correct, but I may be wrong. Try and see.

    CPPFLAGS = ' '.join(filter(lambda x: x.startswith(('-D', '-I', '-i',
    '-U')), cflags))

    Geremy Condra
    geremy condra, Nov 9, 2010
    #2
    1. Advertising

  3. Seebs

    Seebs Guest

    On 2010-11-09, Ben Finney <> wrote:
    > For this purpose, there is a generator expression syntax
    ><URL:http://docs.python.org/reference/expressions.html#generator-expressions>,
    > almost identical to a list comprehension except without the enclosing
    > brackets.
    >
    > ' '.join(x for x in target_cflags.split() if re.match('^-[DIiU]', x))


    Ahh, handy.

    I am torn very much on the generator/comprehension syntax, because on the
    one hand, I really prefer to have the structure first, but on the other hand,
    I can't easily figure out a way to make the syntax work for that.

    > The regex is less clear for the purpose than I'd prefer. For a simple
    > ???is it a member of this small set???, I'd find it more readable to use a
    > simple list of the actual strings::


    > ' '.join(
    > x for x in target_cflags.split()
    > if x in ['-D', '-I', '-i', '-U'])


    The regex is intentionally not anchored with a $, because I'm looking
    for "starts with", not "is".

    > The latter works only in Python with set literals (Python 2.7 or later).


    I think we're stuck with backwards compatibility at least as far as 2.4.

    No, I'm not kidding. *sigh*

    -s
    --
    Copyright 2010, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
    I am not speaking for my employer, although they do rent some of my opinions.
    Seebs, Nov 9, 2010
    #3
  4. Seebs

    Tim Chase Guest

    On 11/08/10 18:34, Seebs wrote:
    > On 2010-11-09, Ben Finney<> wrote:
    >> ' '.join(x for x in target_cflags.split() if re.match('^-[DIiU]', x))

    >
    > Ahh, handy.

    ....
    >> The latter works only in Python with set literals (Python
    >> 2.7 or later).

    >
    > I think we're stuck with backwards compatibility at least as
    > far as 2.4.
    >
    > No, I'm not kidding. *sigh*


    I feel your pain :) At least be glad you don't have to go back
    to 2.3 where Ben's suggested generator-syntax isn't available.

    >> The regex is less clear for the purpose than I'd prefer. For a simple
    >> ???is it a member of this small set???, I'd find it more readable to use a
    >> simple list of the actual strings::

    >
    >> ' '.join(
    >> x for x in target_cflags.split()
    >> if x in ['-D', '-I', '-i', '-U'])

    >
    > The regex is intentionally not anchored with a $, because I'm looking
    > for "starts with", not "is".


    I suppose you could do

    ' '.join(
    x for x in target_cflags.split()
    if x[:2] in ['-D', '-I', '-i', '-U']
    )

    or

    ' '.join(
    x for x in target_cflags.split()
    if x.startswith(('-D', '-I', '-i', '-U'))
    )

    or even

    ' '.join(
    x for x in target_cflags.split()
    if x[:1] == '-' and x[1:2] in 'DIiU'
    )

    -tkc
    Tim Chase, Nov 9, 2010
    #4
  5. Seebs

    Seebs Guest

    On 2010-11-09, Ben Finney <> wrote:
    > Seebs <> writes:
    >> I think we're stuck with backwards compatibility at least as far as
    >> 2.4.


    > Then you don't yet have the ???any??? and ???all??? built-in functions, or the
    > tuple-of-prefixes feature of ???str.startswith??? either. Bummer.


    Eww.

    > At which point, the Pythonic thing to do is to convince your
    > organisation to use a version of Python that's at least officially
    > supported by the PSF :)


    Unfortunately, we're selling something to people who will explode if
    we tell them to upgrade their RHEL4 systems, so we have to work on those.
    (There is some tiny hope that we'll be able to move the baseline to RHEL5
    within another two years.)

    If it were only a matter of internal use, my job would be orders of
    magnitude easier. (I'm maintaining something that intercepts and wraps
    large hunks of the standard C library; if you think dealing with
    Python 2.4 is a burden, you ain't seen *nothing* compared to that.)

    -s
    --
    Copyright 2010, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
    I am not speaking for my employer, although they do rent some of my opinions.
    Seebs, Nov 9, 2010
    #5
  6. Seebs <> writes:

    > I have an existing hunk of Makefile code:
    > CPPFLAGS = "$(filter -D* -I* -i* -U*,$(TARGET_CFLAGS))"
    > For those not familiar with GNU makeisms, this means "assemble a string
    > which consists of all the words in $(TARGET_CFLAGS) which start with one
    > of -D, -I, -i, or -U". So if you give it
    > foo -Ibar baz
    > it'll say
    > -Ibar
    >
    > I have a similar situation in a Python context, and I am wondering
    > whether this is an idiomatic spelling:
    >
    > ' '.join([x for x in target_cflags.split() if re.match('^-[DIiU]', x)])


    You can also use the (less favoured) filter:
    >>> target_cflags="-ifoo -abar -U -Dbaz".split()
    >>> def matches_flags(flags):

    .... return re.compile("^-[%s]" % flags).match
    ....
    >>> ' '.join(filter(matches_flags("DiIU"), target_cflags))

    '-ifoo -U -Dbaz'

    --
    Arnaud
    Arnaud Delobelle, Nov 9, 2010
    #6
  7. Seebs

    Peter Otten Guest

    Seebs wrote:

    > I have an existing hunk of Makefile code:
    > CPPFLAGS = "$(filter -D* -I* -i* -U*,$(TARGET_CFLAGS))"
    > For those not familiar with GNU makeisms, this means "assemble a string
    > which consists of all the words in $(TARGET_CFLAGS) which start with one
    > of -D, -I, -i, or -U". So if you give it
    > foo -Ibar baz
    > it'll say
    > -Ibar
    >
    > I have a similar situation in a Python context, and I am wondering
    > whether this is an idiomatic spelling:
    >
    > ' '.join([x for x in target_cflags.split() if re.match('^-[DIiU]', x)])
    >
    > This appears to do the same thing, but is it an idiomatic use of list
    > comprehensions, or should I be breaking it out into more bits?


    You may be able split and match with a single regex, e. g.

    >>> cflags = "-Dxxx -D zzz -i- -U42-U7 -i -U"


    >>> re.compile(r"-[DIiU]\S*").findall(cflags)

    ['-Dxxx', '-D', '-i-', '-U42-U7', '-i', '-U']

    >>> re.compile(r"-[DIiU]\s*(?:[^-]\S*)?").findall(cflags)

    ['-Dxxx', '-D zzz', '-i', '-U42-U7', '-i ', '-U']

    Peter
    Peter Otten, Nov 9, 2010
    #7
  8. Seebs

    Mark Wooding Guest

    Seebs <> writes:

    > ' '.join([x for x in target_cflags.split() if re.match('^-[DIiU]', x)])
    >
    > This appears to do the same thing, but is it an idiomatic use of list
    > comprehensions, or should I be breaking it out into more bits?


    It looks OK to me. You say (elsewhere in the thread) that you're stuck
    with 2.4 compatibility. I'd personally avoid the regexp, though, and
    write this (actually tested with Python 2.4!):

    ' '.join(i for i in target_cflags.split()
    for p in 'DIiU' if i.startswith('-' + p))

    > You will note that of course, I have carefully made it a one-liner so I
    > don't have to worry about indentation*.


    I failed at that. You have to put up with my indentation.

    -- [mdw]
    Mark Wooding, Nov 9, 2010
    #8
  9. Seebs wrote:
    > I have an existing hunk of Makefile code:
    > CPPFLAGS = "$(filter -D* -I* -i* -U*,$(TARGET_CFLAGS))"
    > For those not familiar with GNU makeisms, this means "assemble a string
    > which consists of all the words in $(TARGET_CFLAGS) which start with one
    > of -D, -I, -i, or -U". So if you give it
    > foo -Ibar baz
    > it'll say
    > -Ibar
    >
    > I have a similar situation in a Python context, and I am wondering
    > whether this is an idiomatic spelling:
    >
    > ' '.join([x for x in target_cflags.split() if re.match('^-[DIiU]', x)])
    >
    > This appears to do the same thing, but is it an idiomatic use of list
    > comprehensions, or should I be breaking it out into more bits?
    >
    > You will note that of course, I have carefully made it a one-liner so I
    > don't have to worry about indentation*.
    >
    > -s
    > [*] Kidding, I just thought this seemed like a pretty clear expression.
    >

    One pythonic way to do it, is to use an option parser.

    optparse (or argparse if python > 2.7)

    JM
    Jean-Michel Pichavant, Nov 9, 2010
    #9
  10. Seebs

    Seebs Guest

    On 2010-11-09, Jean-Michel Pichavant <> wrote:
    > One pythonic way to do it, is to use an option parser.


    That seems like massive overkill -- I don't care about any of the other
    options. It seems like it'd result in doing more work to get and then
    extract the options, and most of that would be discarded instnatly.

    -s
    --
    Copyright 2010, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
    I am not speaking for my employer, although they do rent some of my opinions.
    Seebs, Nov 10, 2010
    #10
  11. On Wed, 10 Nov 2010 00:11:23 +0000, Seebs wrote:

    > On 2010-11-09, Jean-Michel Pichavant <> wrote:
    >> One pythonic way to do it, is to use an option parser.

    >
    > That seems like massive overkill -- I don't care about any of the other
    > options. It seems like it'd result in doing more work to get and then
    > extract the options, and most of that would be discarded instnatly.
    >

    I've always used an extended version of getopt() in C. I was so surprised
    to see that there's nothing equivalent in Java that I wrote my own and
    was consequently was very pleased to find that Python already has the
    optparse module. Using it is a no-brainer, particularly as it makes quite
    a good fist of being self-documenting and of spitting out a nicely
    formatted chunk of help text when asked to do so.


    --
    martin@ | Martin Gregorie
    gregorie. | Essex, UK
    org |
    Martin Gregorie, Nov 10, 2010
    #11
  12. Seebs

    Robert Kern Guest

    On 11/8/10 8:13 PM, Seebs wrote:
    > On 2010-11-09, Ben Finney<> wrote:
    >> Seebs<> writes:
    >>> I think we're stuck with backwards compatibility at least as far as
    >>> 2.4.

    >
    >> Then you don't yet have the ???any??? and ???all??? built-in functions, or the
    >> tuple-of-prefixes feature of ???str.startswith??? either. Bummer.

    >
    > Eww.
    >
    >> At which point, the Pythonic thing to do is to convince your
    >> organisation to use a version of Python that's at least officially
    >> supported by the PSF :)

    >
    > Unfortunately, we're selling something to people who will explode if
    > we tell them to upgrade their RHEL4 systems, so we have to work on those.
    > (There is some tiny hope that we'll be able to move the baseline to RHEL5
    > within another two years.)


    When we deal with such people, we also sell them a recent Python interpreter. :)

    --
    Robert Kern

    "I have come to believe that the whole world is an enigma, a harmless enigma
    that is made terrible by our own mad attempt to interpret it as though it had
    an underlying truth."
    -- Umberto Eco
    Robert Kern, Nov 10, 2010
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. alr
    Replies:
    12
    Views:
    500
  2. Carl J. Van Arsdall
    Replies:
    4
    Views:
    497
    Bruno Desthuilliers
    Feb 7, 2006
  3. Steven W. Orr
    Replies:
    4
    Views:
    277
    Bruno Desthuilliers
    Feb 27, 2007
  4. Troy Melhase
    Replies:
    3
    Views:
    243
    Bruno Desthuilliers
    Feb 25, 2007
  5. Steven W. Orr
    Replies:
    2
    Views:
    253
    goodwolf
    Feb 24, 2007
Loading...

Share This Page