Searching for a pattern in a list of tuples I have written some code to search a for a pattern in a list of tuples. 

It works, but I am sure that it can be improved. Any feedback or ideas would be greatly appreciated.

The list of tuples I am searching in looks like this:


  x = [('A', True), ('B', True), ('C', False), ('D', False), 
       ('X', False), ('E', True), ('F', True), ('G', True)]


I want to find X and then also grab all the values in the tuple adjacent to X that have a value of true.

So the expected output would be:


  X E F G


For:


  y = [('X', True), ('1', True), ('2', True), ('3', True), ('4', False), ('5', True)]


The expected output would be:


  X 1 2 3


For:


  z = [('Dog', True), ('Cow', False), ('Shark', True), ('Cat', True), ('X', False)]


The expected output would be:


  Shark Cat X


For:


  z = [('C', True), ('X', False), ('D', True), ('C', False), ('S', True)]


The expected output would be:


  C X D


This is my code:

test = [('A', False), ('B', False), ('C', True), ('D', True), 
     ('E', True), ('X', False), ('G', True), ('H', False)]

def find_x(x):
    for item in x:
        if item[0] == 'X':
            index = x.index(item)
            return(index)
    return(None)

def look_around(x, index):
    left = 0
    right = len(x)-1    
    found_left = False
    found_right = False

    #look left:
    if index != 0:
        for i in range(index, -1, -1):
            if x[i][1] == True:
                left = i
                found_left = True
            if x[i][1] == False and i != index:
                break

   #look right
    if index != len(x)-1:
        for i in range(index, len(x), +1):
            if x[i][1] == True:
                right = i
                found_right = True
            if x[i][1] == False and i != index:
                break 

    if found_left and found_right:
        return(left, right)
    elif found_left and not found_right:
        return(left, index)
    elif not found_left and found_right:
        return(index, right)
    else:
        return (index, index)

index_of_x = find_x(test)
if index_of_x != None:
    left, right = look_around(test, index_of_x)
    print "match:"
    for i in range (left, right+1, +1):
        print test[i][0], #comma prints everything on same line
If I understand correctly, your problem can be defined as:


take the longest uninterrupted chain of True elements ending in X
take X regardless of value 
take all True elements after X until the first False one


So the actual position of X is not relevant, we only need to know if we encountered it or not. Based on this, we can generate the result with only one pass through the input list. This works if at most one X element is present. 

Bellow you can see my quick and dirty version of the implementation:


from itertools import count, izip
from collections import namedtuple
Elem = namedtuple('Elem', ['name', 'value'])

def valid_elements(elem_lst):
    valid_elem = []
    found_x = False

    for elem in elem_lst:
        if elem.name == 'X':
            found_x = True
            valid_elem.append(elem)
        elif elem.value:
            valid_elem.append(elem)
        elif found_x:
            break
        else:
            valid_elem = []

    if found_x:
        return valid_elem
    return []

z = [Elem('C', True), Elem('X', False), Elem('D', True), Elem('C', False), Elem('S', True)]
print [elem.name for elem in valid_elements(z)]