Re: Pythonic/idiomatic?
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 -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonic/idiomatic?
On Wed, 10 Nov 2010 00:11:23 +, 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 | -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonic/idiomatic?
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 / usenet-nos...@seebs.net 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. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonic/idiomatic?
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 -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonic/idiomatic?
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] -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonic/idiomatic?
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 -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonic/idiomatic?
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 -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonic/idiomatic?
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 / usenet-nos...@seebs.net 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. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonic/idiomatic?
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 -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonic/idiomatic?
Seebs writes: > On 2010-11-09, Ben Finney wrote: > > 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". Ah, okay. Strings have a built-in ‘startswith’ method, but it may be less convenient for the current case compared to a regex. Here's an attempt:: ' '.join( x for x in target_cflags.split() if any( x.startswith(opt_name) for opt_name in ['-D', '-I', '-i', '-U'])) I still find that more readable than the version using a regex, but it's pushing the boundaries of verbosity. Better would be to use the fact that ‘str.startswith’ can do the same as above with a tuple of prefix strings:: ' '.join( x for x in target_cflags.split() if x.startswith(('-D', '-I', '-i', '-U'))) > 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. 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 :-) -- \ “Teach a man to make fire, and he will be warm for a day. Set a | `\ man on fire, and he will be warm for the rest of his life.” | _o__) —John A. Hrastar | Ben Finney -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonic/idiomatic?
On 2010-11-09, Ben Finney wrote: > For this purpose, there is a generator expression syntax >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 / usenet-nos...@seebs.net 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. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonic/idiomatic?
Seebs writes: > 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? One thing to know is that, if you want to create a sequence whose only purpose is to feed to something else and then throw away, a generator will be cleaner and (probably) better performing than a list. For this purpose, there is a generator expression syntax 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)) 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']) or even an actual set:: ' '.join( x for x in target_cflags.split() if x in {'-D', '-I', '-i', '-U'}) The latter works only in Python with set literals (Python 2.7 or later). -- \ “I find the whole business of religion profoundly interesting. | `\ But it does mystify me that otherwise intelligent people take | _o__)it seriously.” —Douglas Adams | Ben Finney -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonic/idiomatic?
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 -- http://mail.python.org/mailman/listinfo/python-list