def common_count(t0, t1):
"returns the length of the longest common prefix"
for i, pair in enumerate(zip(t0, t1)):
if pair[0] != pair[1]:
return i
return i
def group_by_longest_prefix(iterable):
"given a sorted list of strings, group by longest common prefix"
longest = 0
out = []
for t in iterable:
if out: # for there are previous entries
# determine length of prefix in common with prev line
common = common_count(t, out[-1])
# if the current entry has a shorted prefix, output the previous
# entries then start a new group
if common < longest:
yield out
longest = 0
out = []
# otherwise, just update the target prefix length
else:
longest = common
# add the current entry to the group
out.append(t)
# ouput remaining entries as the last group
if out:
yield out
text = """
abcd
abdd
abde
"""
T = sorted(t.strip() for t in text.split("\n") if t)
for L in group_by_longest_prefix(T):
print L
ZGVmIGNvbW1vbl9jb3VudCh0MCwgdDEpOgogICJyZXR1cm5zIHRoZSBsZW5ndGggb2YgdGhlIGxvbmdlc3QgY29tbW9uIHByZWZpeCIKICBmb3IgaSwgcGFpciBpbiBlbnVtZXJhdGUoemlwKHQwLCB0MSkpOgogICAgaWYgcGFpclswXSAhPSBwYWlyWzFdOgogICAgICByZXR1cm4gaQogIHJldHVybiBpCgpkZWYgZ3JvdXBfYnlfbG9uZ2VzdF9wcmVmaXgoaXRlcmFibGUpOgogICJnaXZlbiBhIHNvcnRlZCBsaXN0IG9mIHN0cmluZ3MsIGdyb3VwIGJ5IGxvbmdlc3QgY29tbW9uIHByZWZpeCIKICBsb25nZXN0ID0gMAogIG91dCA9IFtdCgogIGZvciB0IGluIGl0ZXJhYmxlOgogICAgaWYgb3V0OiAjIGZvciB0aGVyZSBhcmUgcHJldmlvdXMgZW50cmllcyAKCiAgICAgICMgZGV0ZXJtaW5lIGxlbmd0aCBvZiBwcmVmaXggaW4gY29tbW9uIHdpdGggcHJldiBsaW5lCiAgICAgIGNvbW1vbiA9IGNvbW1vbl9jb3VudCh0LCBvdXRbLTFdKQoKICAgICAgIyBpZiB0aGUgY3VycmVudCBlbnRyeSBoYXMgYSBzaG9ydGVkIHByZWZpeCwgb3V0cHV0IHRoZSBwcmV2aW91cyAKICAgICAgIyBlbnRyaWVzIHRoZW4gc3RhcnQgYSBuZXcgZ3JvdXAKICAgICAgaWYgY29tbW9uIDwgbG9uZ2VzdDoKICAgICAgICB5aWVsZCBvdXQKICAgICAgICBsb25nZXN0ID0gMAogICAgICAgIG91dCA9IFtdCiAgICAgICMgb3RoZXJ3aXNlLCBqdXN0IHVwZGF0ZSB0aGUgdGFyZ2V0IHByZWZpeCBsZW5ndGgKICAgICAgZWxzZToKICAgICAgICBsb25nZXN0ID0gY29tbW9uCiAgICAKICAgICMgYWRkIHRoZSBjdXJyZW50IGVudHJ5IHRvIHRoZSBncm91cAogICAgb3V0LmFwcGVuZCh0KQoKICAjIG91cHV0IHJlbWFpbmluZyBlbnRyaWVzIGFzIHRoZSBsYXN0IGdyb3VwCiAgaWYgb3V0OgogICAgeWllbGQgb3V0Cgp0ZXh0ID0gIiIiCmFiY2QKYWJkZAphYmRlCiIiIgoKVCA9IHNvcnRlZCh0LnN0cmlwKCkgZm9yIHQgaW4gdGV4dC5zcGxpdCgiXG4iKSBpZiB0KQoKZm9yIEwgaW4gZ3JvdXBfYnlfbG9uZ2VzdF9wcmVmaXgoVCk6CiAgcHJpbnQgTAoK