Returning items which are different from their preceding items from a list I have a list of tuples (key, value1, value2, ...). I simplify the tuple here so it is only of length 2. Keys contain duplicated figures.

xs = zip([1,2,2,3,3,3,4,1,1,2,2], range(11)) # simple to input

[(1, 0),
 (2, 1),
 (2, 2),
 (3, 3),
 (3, 4),
 (3, 5),
 (4, 6),
 (1, 7),
 (1, 8),
 (2, 9),
 (2, 10)]


Now, I would like to build a function, which takes the list as input, and return a list or generator, which is a subset of the original list.

It must captures all items where the keys are changed, and include the first and last items of the list if they are not already there.

f1(xs) = [(1, 0), (2, 1), (3, 3), (4, 6), (1, 7), (2, 9), (2, 10)]
f1([]) = []


The following is my code, it works, but I don't really like it:

xs = zip([1,2,2,3,3,3,4,1,1,2,2], range(11))

def f1(xs):
    if not xs:
        return
    last_a = None # I wish I don't have to use None here.
    is_yield = False
    for a, b in xs:
        if a != last_a:
            last_a = a
            is_yield = True
            yield (a, b)
        else:
            is_yield = False
    if not is_yield:
        yield (a, b) # Ugly...in C# a, b is not defined here.

print list(f1(xs))
print list(f1([]))


What's a better (functional or nonfunctional) way of doing this?
The itertools library has a handy function for this problem called groupby:

def f1(xs):
    for _, group_iter in itertools.groupby(xs, key = lambda pair: pair[0]):
        group = list(group_iter)
        yield group[0]


That'll get us the pairs for which the first element changed from the previous one. Now we just need to make sure we're yield-ing the last element. Which will only NOT be yielded if the last group has size more than 1, hence:

def f1(xs):
    for _, group_iter in itertools.groupby(xs, key = lambda pair: pair[0]):
        group = list(group_iter)
        yield group[0]

    # make sure we yield xs[-1]
    if len(group) &gt; 1:
        yield group[-1]