Chris S
Chris S

Reputation: 49

Function that returns the list index of a substring

I am struggling trying to create a function which searches a list to see if any of the strings contained within it are substrings of any of the other strings within the same list. If a substring is found it should return the index number and if none are found it should return False

For example.

lst1 = ["red", "yellow", "green", "yellowhammer"]
lst2 = ["red", "yellow", "green"]

In this example, lst1 would return a value of 1 as yellow is a substring of yellowhammer and lst2 would return a value of False as there are no substrings.

I have tried the following

templst = lst1
for i in templst:
    if i in lst1:
       return i
    else:
        return False

However this does not work because it always finds itself so even if there are no substrings it returns a value even if it should return False.

Upvotes: 0

Views: 246

Answers (3)

ThunderHorn
ThunderHorn

Reputation: 2035

The following function will return the output you need

def check_subs(lst1):
    answer = {1 if x in y and x !=y else 0 for x in lst1 for y in lst1}
    if sum(answer)>0:
        return answer
    else:
        return False

Upvotes: 0

Samwise
Samwise

Reputation: 71424

First, to create a function, you want to use the def keyword. This is a function that takes a list of strings as its input and returns either a bool or an int, so with type hints it'll look like:

from typing import List, Union

def index_of_substring(strings: List[str]) -> Union[bool, int]:
    """The first index whose item is a substring of a different 
    item in the same list, or False if no such item exists."""
    # implement me
    pass

Now we need to implement the body of the function in terms of its strings argument. Since we want to return the index within the list, it makes sense to iterate over the range of list indices:

    for i in range(len(strings)):

Each i in this loop is an index (e.g. in your list1 it'll be a number from 0 to 3). Now we want to ask the question "is the item at this index a substring of any other item other than itself?"

To answer that question, we want to ask about other indexes in the list that we can compare to our current index i; we'll call those other indexes j:

for j in range(len(strings))

and the conditions we want to satisfy relative to i are:

strings[i] in strings[j] and i != j

We can put this all together in a list comprehension that will give us a list which tells us which items in the range satisfy that and condition:

[strings[i] in strings[j] and i != j for j in range(len(strings))]

and we want to know if any of those items are True:

any([strings[i] in strings[j] and i != j for j in range(len(strings))])

If they are, we want to return i. We want to repeat this check for each i, and if none of them are true, we want to return False. The complete function looks like:

def index_of_substring(strings: List[str]) -> Union[bool, int]:
    for i in range(len(strings)):
        if any([strings[i] in strings[j] and i != j for j in range(len(strings))]):
            return i
    return False

and we can call it like this:

print(index_of_substring(lst1))
print(index_of_substring(lst2))

which prints:

1
False

Upvotes: 0

artemis
artemis

Reputation: 7241

The following code should accomplish what you need. The details of how this is accomplished are commented within.

# Lists that OP provided
lst1 = ["red", "yellow", "green", "yellowhammer"]
lst2 = ["red", "yellow", "green"]

# Function that checks the list
def checkList(myList):
        # Create a variable to hold the concatenated string
        total = ""

        # Build the concatenated string
        for item in myList:
                total += item

        # Loop through the list again
        for i, item in enumerate(myList):
                # Count the amount of times each item appears in the concatenation
                curr = total.count(item)
                # If its more than one, since it will always appear once
                if(curr > 1):
                        # Return its index
                        return i
        # Otherwise, return False
        return False
# Test the two test samples
list_1_ans = checkList(lst1)
list_2_ans = checkList(lst2)

# Print out results
print("First Test Answer: {} | Second Test Answer: {}".format(list_1_ans, list_2_ans))

Yields:

First Test Answer: 1 | Second Test Answer: False

Upvotes: 1

Related Questions