Ordered Count of Characters in Python


The challenge

Count the number of occurrences of each character and return it as a list of tuples in order of appearance. For empty output return an empty list.

Example:

ordered_count("abracadabra") == [('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]

The solution in Python code

Option 1:

from collections import Counter
def ordered_count(input):
    c = Counter(input)
    return sorted(list(c.items()), key=lambda x: input.index(x[0]))

Option 2:

def ordered_count(_input):
    l = []
    for i in _input:
        if i not in l:
            l.append(i)
    return [(i, _input.count(i)) for i in l]

Option 3:

def ordered_count(inp):
    return [(i, inp.count(i)) for i in sorted(set(inp), key=inp.index)]

Test cases to validate our solution

test.describe("Basic Tests")

tests = (
    ('abracadabra', [('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)])
)

for t in tests:
    inp, exp = t
    test.assert_equals(ordered_count(inp), exp)

test.describe("Random Tests")
def random_tests():
    from string import (
        ascii_letters,
        punctuation,
        digits
    )

    from collections import (
        OrderedDict,
        Counter
    )

    from random import (
        randint,
        choice
    )

    class _OrderedCounter(Counter, OrderedDict):
        pass
    
    
    def reference(seq):
        return list(_OrderedCounter(seq).items())
    
    
    CHARS = "".join(("     ", ascii_letters, punctuation, digits))
    
    for _ in range(100):
        test_case = "".join(choice(CHARS) for _ in range(randint(1, 1000)))
        test.assert_equals(ordered_count(test_case), reference(test_case))
        
random_tests()