Is there an easier way to search for an pattern in a list of strings in python?

Viewed 358

I have a list of string and need a better wayt to search for patterns in that list. An exemple of list:

['red','green','red','red','red','red','green','red','red','green','green','red','green','green','red','red','green','green','green','green','green','green','green','red','red','red','red','red','red','green','red','red','red','red','red','red','red','green','green','red','red','green','red','green','green','green','green','green','red','red','green','green','green','red','green','red','green','red','red','green','green','red','green','green','red','red','green','green','red','red','green','green','green','green','red','red','red','red','red','green','green','green','green','red','green','red','green','red','green','red','red','green','red','green','red','green','red','red','red','red','green','red','red','red','green','green','green','red','red','green','green','red','green','red','green','red','green','green','green']

and patterns:

BLUE PATTERN:
['red','green','green','green']
['green','red','red','red']

PINK PATTERN:
['red','green','green','red']
['green','red','red','green']

The method needs to scan my list for patterns and generate another list with the names of the patterns in order that the patterns appeared for exemple:

['blue','pink','blue','blue',..]

That is what i have:

catalogacao = []

if len(self._items) < 4:
    return
for i, _ in enumerate(self._items):
    if i + 4 > len(self._items):
        break
    if self._items[i] == "red" and self._items[i+1] == "green" and self._items[i+2] == "green" and self._items[i+3] == "green":
        catalogacao.append("blue")

    if self._items[i] == "green" and self._items[i+1] == "red" and self._items[i+2] == "red" and self._items[i+3] == "red":
        catalogacao.append("blue")

    if self._items[i] == "red" and self._items[i+1] == "green" and self._items[i+2] == "green" and self._items[i+3] == "red":
        catalogacao.append("pink")

    if self._items[i] == "green" and self._items[i+1] == "red" and self._items[i+2] == "red" and self._items[i+3] == "green":
        catalogacao.append("pink")

3 Answers

You can iterate through your items, and for every sublist of 4 elements, check if the sublist equals a blue or a pink pattern

items = ['red','green','red','red','red','red','green','red','red','green','green','red','green','green','red','red','green','green','green','green','green','green','green','red','red','red','red','red','red','green','red','red','red','red','red','red','red','green','green','red','red','green','red','green','green','green','green','green','red','red','green','green','green','red','green','red','green','red','red','green','green','red','green','green','red','red','green','green','red','red','green','green','green','green','red','red','red','red','red','green','green','green','green','red','green','red','green','red','green','red','red','green','red','green','red','green','red','red','red','red','green','red','red','red','green','green','green','red','red','green','green','red','green','red','green','red','green','green','green']

blue_patterns = [['red','green','green','green'], ['green','red','red','red']]

pink_patterns = [['red','green','green','red'], ['green','red','red','green']]

catalogacao = []

#Iterate over the list
for idx in range(len(items)):

    #Check if the 4 element sublist match blue or pink pattern
    if any(item == items[idx:idx+4] for item in blue_patterns):
        catalogacao.append("blue")

    elif any(item == items[idx:idx+4] for item in pink_patterns):
        catalogacao.append('pink')

print(catalogacao)

The output will be

['blue', 'pink', 'pink', 'pink', 'pink', 'blue', 'blue', 'blue', 'pink', 
'pink', 'blue', 'pink', 'blue', 'pink', 'pink', 'pink', 'pink', 'pink', 
'pink', 'blue', 'blue', 'blue', 'pink', 'blue', 'blue', 'blue', 'pink', 
'pink', 'blue']

This is a little cleaner and simpler :)

pink = [['red','green','green','green'], ['green','red','red','red']]
blue = [['red','green','green','red'], ['green','red','red','green']]
catalogacao = []

for i in range(len(_items) - 4):
    colors = [x for x in _items[i:i+4]]
    if colors in blue:
        catalogacao.append("blue")
    elif colors in pink:
        catalogacao.append("pink")

ASk if any questions! :)

why not use regular expressions?

we first put your patterns together in a more machine friendly format, then compile them into a regular expression:

patterns = (
    (['red','green','green','green'], 'blue'),
    (['green','red','red','red'], 'blue'),
    (['red','green','green','red'], 'pink'),
    (['green','red','red','green'], 'pink'),
)

pattern_dict = {
    ' '.join(words): out  for words, out in patterns
}

pattern_re = re.compile('|'.join(pattern_letters.keys()))

then we can apply this to your items:

items = ['red','green','red','red','red','red','green','red','red','green','green','red','green','green','red','red','green','green','green','green','green','green','green','red','red','red','red','red','red','green','red','red','red','red','red','red','red','green','green','red','red','green','red','green','green','green','green','green','red','red','green','green','green','red','green','red','green','red','red','green','green','red','green','green','red','red','green','green','red','red','green','green','green','green','red','red','red','red','red','green','green','green','green','red','green','red','green','red','green','red','red','green','red','green','red','green','red','red','red','red','green','red','red','red','green','green','green','red','red','green','green','red','green','red','green','red','green','green','green']

output = []
for match in pattern_re.finditer(' '.join(items)):
    pat = match.group(0)
    output.append(pattern_dict[pat])
Related