In Python, I would not use anything other than the existing commonprefix function, which I showed in another answer, but I could not help reinvent the wheel :P This is my iterator based approach:
>>> a = 'interspecies interstelar interstate'.split() >>> >>> from itertools import takewhile, chain, izip as zip, imap as map >>> ''.join(chain(*takewhile(lambda s: len(s) == 1, map(set, zip(*a))))) 'inters'
Edit: An explanation of how this works.
zip generates tuples of elements that take one of each element a at a time:
In [6]: list(zip(*a)) # here I use list() to expand the iterator Out[6]: [('i', 'i', 'i'), ('n', 'n', 'n'), ('t', 't', 't'), ('e', 'e', 'e'), ('r', 'r', 'r'), ('s', 's', 's'), ('p', 't', 't'), ('e', 'e', 'a'), ('c', 'l', 't'), ('i', 'a', 'e')]
By matching set on these elements, I get a series of unique letters:
In [7]: list(map(set, _)) # _ means the result of the last statement above Out[7]: [set(['i']), set(['n']), set(['t']), set(['e']), set(['r']), set(['s']), set(['p', 't']), set(['a', 'e']), set(['c', 'l', 't']), set(['a', 'e', 'i'])]
takewhile(predicate, items) accepts elements from this, while the predicate is True; in this particular case, when set has one element, i.e. all words have the same letter in this position:
In [8]: list(takewhile(lambda s: len(s) == 1, _)) Out[8]: [set(['i']), set(['n']), set(['t']), set(['e']), set(['r']), set(['s'])]
At this moment, we have the iterability of the sets, each of which contains one letter of the prefix we were looking for. To build a string, we chain them into one iterable, from which we get the letters in join to the final string.
The magic of using iterators is that all elements are generated on demand, so when takewhile stops asking for elements, zping stops at that moment and no unnecessary work is done. Each function call in my single-line line has an implicit for and an implicit break .