Reputation: 49
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
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
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
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