How do i display word with missing first letter? - python-3.x

i get a TypeError saying can't convert 'list' object to str implicitly
# list of words to choose from and get a random word using the random module's sample method
list_of_words = ['apple', 'banana', 'watermelon', 'kiwi', 'pineapple', 'mango']
word = random.sample(list_of_words,1)
# showcase to the player the random word with first letter missing
chosen_word = word[1:]
print('The answer so far is _' + chosen_word)
I expect the output to be for example: The answer so far is _anana

random.sample picks multiple random elements from the input sequence, according to the number given for the second argument. Because it is meant to return a variable number of elements, it returns them in a list, even if you specified that you only want one.
Therefore word is a list with one element and
word[1:]
is a sliced version of that list (the empty list), but still a list. The error message tells you, that you cannot add a list to a string by relying on an implicit conversion of the list to a string representation. What you actually want to apply [1:] to is not the list, but the element in it. So you need to select it first with word[0] (take the first element of word), then you can slice the string: word[0][1:].
If you always want only one element, you can also use random.choice instead of random.sample, which doesn't take the second argument and always returns only one randomly chosen element, not as list:
word = random.choice(list_of_words)
chosen_word = word[1:]

Related

A simple basic Python3 question which I don't Understand

Question:
Fill in the function body for the Python3 function longestWord (you should leave the function header as it appears).
The function takes a single input argument which we assume is a list of strings, with each string forming one English word. The output should be a word from the list which has the greatest number of letters.
You must use a for loop to write this function.
Answer:
def longestWord(listOfWords):
biggestWord = listOfWords[0]
biggestNum = len(biggestWord)
for word in listOfWords:
num = len(word)
if num>biggestNum:
biggestNum=num
biggestWord=word
return biggestWord
print(longestWord(["Hello", "Goodbye"]))
I understand the first three lines. It takes the first value in the list and saves the length of the word inputted. However i don't understand the rest of the code. How does it compare the two inputted words to output the longest one. What is num and word?. Thank you.
I'd like to inform you that this question is about Python3 and not C++. Anyways, what the code is doing is it's taking the first word and stores it in a variable called biggestWord. and storing the length of biggestWord in a variable called biggestNum. Then for each word in listOfWords, it stores the word in a variable called word and stroing the length of it in variable called num. Then it compares num and biggestNum. If the length of some word i.e. num is bigger than the biggest length up until now, i.e. biggestNum, then it puts num in biggestNum to indicate that that's the biggest number up until now. and puts word in biggestWord replacing the old word. Then it returns the word with the biggest length, i.e. biggestWord.

Python - how to recursively search a variable substring in texts that are elements of a list

let me explain better what I mean in the title.
Examples of strings where to search (i.e. strings of variable lengths
each one is an element of a list; very large in reality):
STRINGS = ['sftrkpilotndkpilotllptptpyrh', 'ffftapilotdfmmmbtyrtdll', 'gftttepncvjspwqbbqbthpilotou', 'htfrpilotrtubbbfelnxcdcz']
The substring to find, which I know is for sure:
contained in each element of STRINGS
is also contained in a SOURCE string
is of a certain fixed LENGTH (5 characters in this example).
SOURCE = ['gfrtewwxadasvpbepilotzxxndffc']
I am trying to write a Python3 program that finds this hidden word of 5 characters that is in SOURCE and at what position(s) it occurs in each element of STRINGS.
I am also trying to store the results in an array or a dictionary (I do not know what is more convenient at the moment).
Moreover, I need to perform other searches of the same type but with different LENGTH values, so this value should be provided by a variable in order to be of more general use.
I know that the first point has been already solved in previous posts, but
never (as far as I know) together with the second point, which is the part of the code I could not be able to deal with successfully (I do not post my code because I know it is just too far from being fixable).
Any help from this great community is highly appreciated.
-- Maurizio
You can iterate over the source string and for each sub-string use the re module to find the positions within each of the other strings. Then if at least one occurrence was found for each of the strings, yield the result:
import re
def find(source, strings, length):
for i in range(len(source) - length):
sub = source[i:i+length]
positions = {}
for s in strings:
# positions[s] = [m.start() for m in re.finditer(re.escape(sub), s)]
positions[s] = [i for i in range(len(s)) if s.startswith(sub, i)] # Using built-in functions.
if not positions[s]:
break
else:
yield sub, positions
And the generator can be used as illustrated in the following example:
import pprint
pprint.pprint(dict(find(
source='gfrtewwxadasvpbepilotzxxndffc',
strings=['sftrkpilotndkpilotllptptpyrh',
'ffftapilotdfmmmbtyrtdll',
'gftttepncvjspwqbbqbthpilotou',
'htfrpilotrtubbbfelnxcdcz'],
length=5
)))
which produces the following output:
{'pilot': {'ffftapilotdfmmmbtyrtdll': [5],
'gftttepncvjspwqbbqbthpilotou': [21],
'htfrpilotrtubbbfelnxcdcz': [4],
'sftrkpilotndkpilotllptptpyrh': [5, 13]}}

Doubts about string

So, I'm doing an exercise using python, and I tried to use the terminal to do step by step to understand what's happening but I didn't.
I want to understand mainly why the conditional return just the index 0.
Looking 'casino' in [Casinoville].lower() isn't the same thing?
Exercise:
Takes a list of documents (each document is a string) and a keyword.
Returns list of the index values into the original list for all documents containing the keyword.
Exercise solution
def word_search(documents, keyword):
indices = []
for i, doc in enumerate(documents):
tokens = doc.split()
normalized = [token.rstrip('.,').lower() for token in tokens]
if keyword.lower() in normalized:
indices.append(i)
return indices
My solution
def word_search(documents, keyword):
return [i for i, word in enumerate(doc_list) if keyword.lower() in word.rstrip('.,').lower()]
Run
>>> doc_list = ["The Learn Python Challenge Casino.", "They bought a car", "Casinoville"]
Expected output
>>> word_search(doc_list, 'casino')
>>> [0]
Actual output
>>> word_search(doc_list, 'casino')
>>> [0, 2]
Let's try to understand the difference.
The "result" function can be written with list-comprehension:
def word_search(documents, keyword):
return [i for i, word in enumerate(documents)
if keyword.lower() in
[token.rstrip('.,').lower() for token in word.split()]]
The problem happens with the string : "Casinoville" at index 2.
See the output:
print([token.rstrip('.,').lower() for token in doc_list[2].split()])
# ['casinoville']
And here is the matter: you try to ckeck if a word is in the list. The answer is True only if all the string matches (this is the expected output).
However, in your solution, you only check if a word contains a substring. In this case, the condition in is on the string itself and not the list.
See it:
# On the list :
print('casino' in [token.rstrip('.,').lower() for token in doc_list[2].split()])
# False
# On the string:
print('casino' in [token.rstrip('.,').lower() for token in doc_list[2].split()][0])
# True
As result, in the first case, "Casinoville" isn't included while it is in the second one.
Hope that helps !
The question is "Returns list of the index values into the original list for all documents containing the keyword".
you need to consider word only.
In "Casinoville" case, word "casino" is not in, since this case only have word "Casinoville".
When you use the in operator, the result depends on the type of object on the right hand side. When it's a list (or most other kinds of containers), you get an exact membership test. So 'casino' in ['casino'] is True, but 'casino' in ['casinoville'] is False because the strings are not equal.
When the right hand side of is is a string though, it does something different. Rather than looking for an exact match against a single character (which is what strings contain if you think of them as sequences), it does a substring match. So 'casino' in 'casinoville' is True, as would be casino in 'montecasino' or 'casino' in 'foocasinobar' (it's not just prefixes that are checked).
For your problem, you want exact matches to whole words only. The reference solution uses str.split to separate words (the with no argument it splits on any kind of whitespace). It then cleans up the words a bit (stripping off punctuation marks), then does an in match against the list of strings.
Your code never splits the strings you are passed. So when you do an in test, you're doing a substring match on the whole document, and you'll get false positives when you match part of a larger word.

Finding position of first letter in subtring in list of strings (Python 3)

I have a list of strings, and I'm trying to find the position of the first letter of the substring I am searching for in the list of strings. I'm using the find() method to do this, however when I try to print the position of the first letter Python returns the correct position but then throws a -1 after it, like it couldn't find the substring, but only after it could find it. I want to know how to return the position of the first letter of he substring without returning a -1 after the correct value.
Here is my code:
mylist = ["blasdactiverehu", "sdfsfgiuyremdn"]
word = "active"
if any(word in x for x in mylist) == True:
for x in mylist:
position = x.find(word)
print(position)
The output is:
5
-1
I expected the output to just be:
5
I think it may be related to the fact the loop is searching for the substring for every string in the list and after it's found the position it still searches for more but of course returns an error as there is only one occurrence of the substring "active", however I'm not sure how to stop searching after successfully finding one substring. Any help is appreciated, thank you.
Indeed your code will not work as you want it to, since given that any of the words contain the substring, it will do the check for each and every one of them.
A good way to avoid that is using a generator. More specifically, next()
default_val = '-1'
position = next((x.find(word) for x in mylist if word in x), default_val)
print(position)
It will simply give you the position of the substring "word" for the first string "x" that will qualify for the condition if word in x, in the list 'mylist'.
By the way, no need to check for == True when using any(), it already returns True/False, so you can simply do if any(): ...

Pass a string and compare it to a list

I am passsing an argument through robot framework. The argument is a string. "Detroit".
I want the code to break down that string to "D", "De", "Det", "Detr", "Detro","Detroi", and "Detroit". Of course if another string is entered, say "Flint" it would only break it down into the 5 elements. F, Fl, Fli, Flin, Flint.
(Pseudo Code)
def checkCity (self, x):
(take x which is the string, and make it a list of elements containing the letters as above).
(Then take each element and check it against data provided by the device(using a loop for each iteration)
(Once any of the elements are matched to the data, return another function that acts as a key press)
I'm familiar enough with python (and programming) in general to have the theory, just don't know how to code it.
I'm not familiar with the programming language that you are using but I will help out as much as I can.
For breaking down the string, you could use a while loop or a for loop, whichever you prefer. The ending condition being the length of the string that you put into the second parameter. In the loop, you can use substring method to break down the string and store each element into an array list.
Then for checking if any of the elements are matched, you would (as you have said) use a loop for each iteration.
In python you can access individual parts of a string by using
string[5:7]
That would give the 5th and 6th characters
This function in python will return a list like the one you want
def toSubLists(string):
sublists = []
for i in range(1, len(string)+1):
sublists.append(string[0:i])
return sublists

Resources