OK, If I might tell some story... :) Main motivation was a use case where we gather command line options, and some of them are… optional. Below is a realistic example. Namely options for LLVM Clang:
flags = [“-O3”, “-fomit-frame-pointer”, maybe_pgo(context)]
Here “maybe_pgo” returns either “None” if we don’t use profile guided optimization and it returns “-fprofile-generate” otherwise. Thus I have collection of options and some of them are empty or None. In order to get rendered command line options string I use “compress” in conjunction with “join":
opts = " ".join(compress(flags, flags))
I usually introduce alias for this:
def jin(a: str, sep=“ “): return sep.join(compress(a, a))
And I found that I use it quite frequently. (“jin” is an analog of “join" but without “emptiness”, so we omitted “o” :) ) Initially I also used this:
it = (x for x in it if x)
But when you about to build sophisticated options string it leads to quite scattered code. Whilst with an alias I make pretty readable one-liners:
opts = “ “.join(compress([“-O3”, “-fomit-stackpointer”, maybe_linker_pgo(context)]))
or in case with “str.jin”:
opts = " ".jin([“-O3”, “-fomit-stackpointer”, maybe_linker_pgo(context)])
I considered to propose “str.jin” static method, and pretty much wondered about it. But then decided that for stdlib and might be too much and stopped on “compress”. Also it still allows to build options collection in a nice way if you surround all options lists with a “compress” call:
flags = compress([“-O3”, “-fomit-stackpointer”, *maybe_even_more(context)]) ldflags = compress([“-fglobal-merge”, maybe_opt_level(context)] opts = " “.join(flags + ldflags)
What confuses me with “compress” is a weird dispersion of similar functionality: “filter” (builtin), “itertools.compress” and “itertools.filterfalse”. All of them pursues similar goals and in fact might be redesigned as a single method. Or methods family with same prefix (“filter”?). And perhaps it was discussed already. So wouldn’t it be wasted effort to work on “compress” right now? Perhaps “jin” would be better a solution indeed? And yet I’m solid that we need some compact and nice way for rendering strings with command options. That would be a thing. Thanks! Stepan Dyatkovskiy
On Sep 14, 2021, at 2:19 AM, Tim Peters
wrote: FYI, itertools.compress() is very useful in conjunction with itertools.cycle() to pick out elements following a periodic pattern of indices. For example,
# Elements at even indices.
list(compress(range(20), cycle([1, 0]))) [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
# Or at odd ones.
list(compress(range(20), cycle([0, 1]))) [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
# Pick every third.
list(compress(range(20), cycle([0, 0, 1]))) [2, 5, 8, 11, 14, 17]
# Omit every third.
list(compress(range(20), cycle([1, 1, 0]))) [0, 1, 3, 4, 6, 7, 9, 10, 12, 13, 15, 16, 18, 19]
For arguments that are re-iteraerable, there are several ways to get the proposed semantics, including just passing the argument twice to compress():
a = [None, "", "-filove-python", "CFLAGS=-O3"] " ".join(compress(a, a)) '-filove-python CFLAGS=-O3'
Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/XGCVW3... Code of Conduct: http://python.org/psf/codeofconduct/