[Python-ideas] os.path.commonprefix: Yes that old chestnut.

Andrew Barnert abarnert at yahoo.com
Tue Mar 24 16:32:51 CET 2015


On Mar 24, 2015, at 8:15 AM, Paul Moore <p.f.moore at gmail.com> wrote:
> 
>> On 24 March 2015 at 14:44, Andrew Barnert <abarnert at yahoo.com> wrote:
>> From my other reply, looking over the functions used in some of the rosettacode examples, it looks like the generic iterable function, when it exists, and the language makes it feasible, often handles an arbitrary number of arguments, not just two. Which makes sense, now that I think about it. So:
>> 
>>    def common_prefix(*iterables):
>>        for first, *rest in zip(*iterables):
>>            if any(first != part for part in rest):
>>                return
>>            yield first
> 
> Thanks for the research. This is probably something that could be
> included as a recipe in the itertools documentation. (I doubt it would
> be viewed as a common enough requirement to be added to the module
> itself...) Do you have any objection to me submitting a doc patch with
> this code? (It's similar to what I came up with, but a lot cleaner).

I agree that it belongs as a recipe in itertools (and of course it can go into the third-party more-itertools library on PyPI for people who want to just import and use it, as with the other useful recipes).

But you probably want to test it first, and make sure I thought through the stupid edge cases like no iterables or empty iterables, since that's just off the top of my head, and while tired and recovering from a cold to boot. :)

Also, while I think this generic function is useful on its own merits, it doesn't solve the problem that started this thread--as pointed out by (I forget who), just using it on the string parts gives the wrong answer for Windows paths. Should there also be a recipe in the pathlib docs referencing the itertools recipe? (Is it even reasonable for a recipe in one module's docs to rely on a recipe in another's?) Or maybe, as Tal (I think) suggested, a better solution is to avoid the problem and use parents instead of parts, meaning you don't even need a common_prefix recipe, but a last_initial_match (although that's just last(common_prefix(*args)), so maybe that doesn't really matter.)


More information about the Python-ideas mailing list