ohid
ohid

Reputation: 914

Find word vertically from 2D crosswords or 2D lists

I have written some python code to find row and column indices from a 2D crossword, searching vertically. My code is:

def find_word_vertical(crosswords,word):
    l=[]
    for i in range(len(crosswords[0])):
            l.append(''.join([row[i] for row in crosswords]))
            print(l)            
            if word in l:   #finding index
                row_index=crosswords.index(i)
                column_index=i.index(word[0])
                print(row_index,column_index)
                return [row_index,column_index ]
    return None
crosswords=[['s','d','o','g'],['c','u','c','m'],['a','c','a','t'],['t','e','t','k']]
word='cat'
print(find_word_vertical(crosswords,word))

My code is currently returning None, but it should be returning the index values [1,0].

How can I get column index and row index correctly from crosswords for selected word(cat)?

Upvotes: 0

Views: 1158

Answers (3)

ohid
ohid

Reputation: 914

def find_word_vertical(crosswords,word):
    z=[list(i) for i in zip(*crosswords)]   
    for rows in z:          
        row_index = z.index(rows)
        single_row = ''.join(rows)      
        column_index = single_row.find(word)        
        if column_index >= 0:
            return([column_index, row_index])

I modified the codes and this code give me correct index [1,0]

Upvotes: 2

Tersosauros
Tersosauros

Reputation: 923

The crux of the issue with your code is some misuse of the Python list index method. Specifically, upon line #7 of the code (as posted). you appear to be using index to perform a list lookup (normally done using the square braces []).

Additionally, you also appear to have some type confusion (which is easy when starting in a loosely typed language such as Python) happening. This occurs because the l variable (which I'm assuming was a shorthand for line?) is a list, not a string. Because of this, the condition word in l would never be true - hence making your program ALWAYS return None as if no match existed.


Code:

The below code works:

def find_word_vertical(crosswords,word):
    l=[]
    for i in range(len(crosswords[0])):
            l.append(''.join([row[i] for row in crosswords]))
            for line in l:
                if word in line:   #finding index
                    row_index=i
                    column_index=line.index(word[0])
                    return (row_index,column_index)
    raise Exception("Unable to find word vertically!")

crosswords=[['s','d','o','g'],['c','u','c','m'],['a','c','a','t'],['t','e','t','k']]
word='cat'

print(find_word_vertical(crosswords,word))

Changes:

  1. Added the for line in l: loop (line #5), this gets around the type-confusion issue you were having. Note:  There may be other (possibly better) ways around this.

  2. Changed row_index to just be set to i - since we're already iterating in that dimension with that variable.

  3. Changed column_index to make use of line, rather than i (which is just a counter).

  4. This one wasn't technically necessary, and you may wish not to use it.. but I removed the return None and replaced this with an Exception (better practice for an unexpected algorithmic result).


Other Recommendations:

  • Your "main" style code (i.e. the definition of crosswords, word and the print line which calls your function) would best be put into an if __name__=="__main__": block.

  • Avoid single letter variable names (like l) for important things (like what you're using l for here). I would change this to be vertical_line or similar.

  • The argument you supply to range in the first for loop, makes the assumption that all crossword lines are the same length You have no logic anywhere I can see to enforce this.


When you are done with your program, please consider posting it on the Code Review site for review.

Upvotes: 0

Tersosauros
Tersosauros

Reputation: 923

Your code is returning None because on line 11 you literally return None.

I suspect you mean to be returning l?

Upvotes: -1

Related Questions