2

This is a pretty simple question about lists and for loop.

Assuming I have the following 2d-list:

[

['c', 'a', 't', 'c', 'a', 't']

['a', 'b', 'c', 'a', 't, 'l']

['c', 'a', 't', 'w', 'x', 'y']

]

And I want to iterate over the list using for loops, each time checking if the word 'cat' is in the list. If it is, I want to add it to the list every time it appears.

So my result should be ['cat', 'cat', 'cat, 'cat']

My function receives a word list and a given matrix (2d list containing lists of letters). My code is:

def search_for_words(word_list, matrix):
    results = []
    for word in word_list:
        for line in matrix:
            line_string = ''.join(line)
                if word in line_string:
                    results.append(word)
    return results

And it will returns me just 'cat' if cat is in thr word list.

I know I probably just need another if statement but I can figure it out.

Thanks in advance.

EDIT:

I gave a wrong example.

consider this:

matrix = [['a', 'p', 'p', 'l', 'e'], 
      ['a', 'g', 'o', 'd', 'o'],
      ['n', 'n', 'e', 'r', 't'],
      ['g', 'a', 'T', 'A', 'C'],
      ['m', 'i', 'c', 's', 'r'],
      ['P', 'o', 'P', 'o', 'P']]

word_list = ['apple', 'god', 'dog', 'CAT', 'PoP', 'poeT]

my function returns :

['apple', 'god', 'PoP']

When I expect it to return 'PoP' twice because it appears twice at the bottom list.

Tegernako
  • 289
  • 1
  • 9
  • 1
    Welcome to SO! Can't reproduce your problem, code produces the correct output, assuming you fix your indentation error. – ggorlen Nov 18 '18 at 20:28
  • For me, the returned list has 3 occurrences of `cat` (instead of 4) but that is a different problem. – slider Nov 18 '18 at 20:34
  • I edited my question with the appropriate example. Sorry for the confusion. @ggorlen – Tegernako Nov 18 '18 at 20:38
  • the line `if word in line_string` checks for the `word` in `line_string` only once. you will need to find the index of the first match then again look for the next match starting from the `index of the last match + 1` – Rahul Virpara Nov 18 '18 at 20:46

2 Answers2

4

The problem is you're not checking how many times that substring occurs in the string. You also need to account for overlapping matches:

import re

def search_for_words(word_list, matrix):
    results = []
    for word in word_list:
        for line in matrix:
            line_string = ''.join(line)
            # find all overlapping matches of word in line_string
            matches = re.findall(r'(?=(' + word + '))', line_string)
            results.extend(matches)
    return results

If we run this on your second matrix:

m = [['a', 'p', 'p', 'l', 'e'], 
     ['a', 'g', 'o', 'd', 'o'],
     ['n', 'n', 'e', 'r', 't'],
     ['g', 'a', 'T', 'A', 'C'],
     ['m', 'i', 'c', 's', 'r'],
     ['P', 'o', 'P', 'o', 'P']]

word_list = ['apple', 'god', 'dog', 'CAT', 'PoP', 'poeT']

print(search_for_words(word_list, m))

we see the following output:

['apple', 'god', 'PoP', 'PoP']
slider
  • 12,810
  • 1
  • 26
  • 42
1

The answer to your first question is pretty simple. Just build a string and check it each time. Lose the first letter of the string if the string is longer than the target word.

outer = [['c', 'a', 't', 'c', 'a', 't'],
         ['a', 'b', 'c', 'a', 't', 'l'],
         ['c', 'a', 't', 'w', 'x', 'y']]

for inner in outer:
  word = ""
  target = "cat"
  t_len = len(target)
  for letter in inner:
    word += letter
    if len(word) > t_len:
      word = word[1:]
    if word in target:
      print(target)

For the answer to your second question, you're probably best to just "".join() all of the strings and parse them with regex.

NotAnAmbiTurner
  • 2,553
  • 2
  • 21
  • 44