I got a working solution to this question with my second attempt. But I'm wondering why the first option doesn't work as well.
The question is:
Complete the function to replace the word test with cat and print the new string
my code (working solution):
def replaceTest(mystring):
answer = mystring.replace("test", "cat")
print(answer)
replaceTest('This is a test')
# output:
# This is a cat
my code (solution that doesn't work):
def replaceTest(mystring):
stringSplit = mystring.split()
for i in stringSplit:
if i == 'test':
i = 'cat'
answer = " ".join(stringSplit)
print(answer)
print(replaceTest('This is a test'))
# output:
# This is a test
# None
I can't see why it doesn't work. I think I'm iterating over each item in the list and saying if that item is test, make it cat instead. And then making the list into a string. Where did i go wrong?
With i = 'cat' you are just assigning to the loop variable, which is then discarded. You need to assign to the original strinSplit list (stringSplit[i] = 'cat') where by i is the index of stringSplit, obtained from enumerate:
def replaceTest(mystring):
stringSplit = mystring.split()
for i, word in enumerate(stringSplit):
if word == 'test':
stringSplit[i] = 'cat'
answer = " ".join(stringSplit)
print(answer)
replaceTest('This is a test')
Some improvements while still using your original logic: Having an index in a loop used to access list elements is awkward and error-prone. In this case (and many others) you can avoid it using a list comprehension instead. Also, I assume you wouldn't really want to print inside the function but instead return the modified string so you can use it further:
def replaceTest(mystring):
string_split_replace = ["cat" if word == "test" else word
for word in mystring.split()]
return " ".join(string_split_replace)
print(replaceTest('This is a test'))
I want to write a python function that takes 2 parameters:
List of words and
Ending letters
I want my function to work in such a way that it modifies the original list of words and removes the words which end with the "ending letters" specified.
For example:
list_words = ["hello", "jello","whatsup","right", "cello", "estello"]
ending = "ello"
my_func(list_words, ending)
This should give the following output:
list_words = ["whatsup","right"]
It should pop off all the strings that end with the ending letters given in the second argument of the function.
I can code this function using the .endswith method but I am not allowed to use it. How else can I do this using a loop?
Try:
def my_func(list_words, ending):
return [word for word in list_words if word[len(word)-len(ending):] != ending]
def filter_words(list_words, ending):
return [*filter(lambda x: x[-len(ending):] != ending , list_words)]
Not allowed to use endswith? Not a problem :-P
def my_func(list_words, ending):
list_words[:] = [word for word in list_words
if not word[::-1].startswith(ending[::-1])]
return list_words
Loopholes ftw.
(Adapted to your insistence on modifying the given list. You should probably really decide whether to modify or return, though, not do both, which is rather unusual in Python.)
You can easily check for the last4 characters of a string using string[-4:].
So you can use the below code
list_words = ["hello", "jello","whatsup","right", "cello", "estello"]
ending = "ello"
def my_func(wordsArray, endingStr):
endLen = len(endingStr)
output = []
for x in wordsArray:
if not x[-endLen:] == endingStr:
output.append(x)
return output
list_words = my_func(list_words, ending)
You can shorten the function with some list comprehension like this:
def short_func(wordsArray, endingStr):
endLen = len(endingStr)
output = [x for x in wordsArray if x[-endLen:] != endingStr]
return output
list_words = short_func(list_words, ending)
It is always better to not modify the existing list you can get a list which doesn't have the words with the ending specified like below. If you want to have it as a function you can have it in a following manner. You can assign the formatted list to list_words again.
def format_list(words, ending):
new_list = []
n = len(ending)
for word in words:
if len(word) >= n and n > 0:
if not word[-n:] == ending:
new_list.append(word)
else:
new_list.append(word)
return new_list
list_words = format_list(list_words, ending)
print(list_words)
I want to check for each position in the string what is the character that appears most often on that position. If there are more of the same frequency, keep the first one. All strings in the list are guaranteed to be of identical length!!!
I tried the following way:
print(max(((letter, strings.count(letter)) for letter in strings), key=lambda x:[1])[0])
But I get: mistul or qagic
And I can not figure out what's wrong with my code.
My list of strings looks like this:
Input: strings = ['mistul', 'aidteh', 'mhfjtr', 'zxcjer']
Output: mister
Explanation: On the first position, m appears twice. Second, i appears twice twice. Third, there is no predominant character, so we chose the first, that is, s. On the fourth position, we have t twice and j twice, but you see first t, so we stay with him, on the fifth position we have e twice and the last r twice.
Another examples:
Input: ['qagic', 'cafbk', 'twggl', 'kaqtc', 'iisih', 'mbpzu', 'pbghn', 'mzsev', 'saqbl', 'myead']
Output: magic
Input: ['sacbkt', 'tnqaex', 'vhcrhl', 'obotnq', 'vevleg', 'rljnlv', 'jdcjrk', 'zuwtee', 'xycbvm', 'szgczt', 'imhepi', 'febybq', 'pqkdfg', 'swwlds', 'ecmrut', 'buwruy', 'icjwet', 'gebgbq', 'djtfzr', 'uenleo']
Expected Output: secret
Some help?
Finally a use case for zip() :-)
If you like cryptic code, it could even be done in one statement:
def solve(strings):
return ''.join([max([(letter, letters.count(letter)) for letter in letters], key=lambda x: x[1])[0] for letters in zip(*strings)])
But I prefer a more readable version:
def solve(strings):
result = ''
# "zip" the strings, so in the first iteration `letters` would be a list
# containing the first letter of each word, the second iteration it would
# be a list of all second letters of each word, and so on...
for letters in zip(*strings):
# Create a list of (letter, count) pairs:
letter_counts = [(letter, letters.count(letter)) for letter in letters]
# Get the first letter with the highest count, and append it to result:
result += max(letter_counts, key=lambda x: x[1])[0]
return result
# Test function with input data from question:
assert solve(['mistul', 'aidteh', 'mhfjtr', 'zxcjer']) == 'mister'
assert solve(['qagic', 'cafbk', 'twggl', 'kaqtc', 'iisih', 'mbpzu', 'pbghn',
'mzsev', 'saqbl', 'myead']) == 'magic'
assert solve(['sacbkt', 'tnqaex', 'vhcrhl', 'obotnq', 'vevleg', 'rljnlv',
'jdcjrk', 'zuwtee', 'xycbvm', 'szgczt', 'imhepi', 'febybq',
'pqkdfg', 'swwlds', 'ecmrut', 'buwruy', 'icjwet', 'gebgbq',
'djtfzr', 'uenleo']) == 'secret'
UPDATE
#dun suggested a smarter way of using the max() function, which makes the one-liner actually quite readable :-)
def solve(strings):
return ''.join([max(letters, key=letters.count) for letters in zip(*strings)])
Using collections.Counter() is a nice strategy here. Here's one way to do it:
from collections import Counter
def most_freq_at_index(strings, idx):
chars = [s[idx] for s in strings]
char_counts = Counter(chars)
return char_counts.most_common(n=1)[0][0]
strings = ['qagic', 'cafbk', 'twggl', 'kaqtc', 'iisih',
'mbpzu', 'pbghn', 'mzsev', 'saqbl', 'myead']
result = ''.join(most_freq_at_index(strings, idx) for idx in range(5))
print(result)
## 'magic'
If you want something more manual without the magic of Python libraries you can do something like this:
def f(strings):
dic = {}
for string in strings:
for i in range(len(string)):
word_dic = dic.get(i, { string[i]: 0 })
word_dic[string[i]] = word_dic.get(string[i], 0) + 1
dic[i] = word_dic
largest_string = max(strings, key = len)
result = ""
for i in range(len(largest_string)):
result += max(dic[i], key = lambda x : dic[i][x])
return result
strings = ['qagic', 'cafbk', 'twggl', 'kaqtc', 'iisih', 'mbpzu', 'pbghn', 'mzsev', 'saqbl', 'myead']
f(strings)
'magic'
I have found synonyms of a word "plant"
syn = wordnet.synsets('plant')[0].lemmas()
>>>[Lemma('plant.n.01.plant'), Lemma('plant.n.01.works'), Lemma('plant.n.01.industrial_plant')]
and an input word
word = 'work'
I want to find if 'work' appears in syn. How to do it?
Lemma's have a name() method so what you could do is
>>> 'works' in map(lambda x: x.name(), syn)
True
Edit: did not see you said "work", not works, so this would be:
>>> for i in syn:
... if 'work' in i.name():
... print True
...
True
You can wrap it in a function for example.
Or a mixture of the two suggestions I made:
any(map(lambda x: 'work' in x, map(lambda x: x.name(), syn)))
You can easily check for the presence of a substring using the keyword in in python:
>>> word = "work"
>>> word in 'plant.n.01.works'
True
>>> word in 'plant.n.01.industrial_plant'
False
If you want to test this in a list you can do a loop:
syn = ["plant.one","plant.two"]
for plant in syn:
if word in plant:
print("ok")
Or better a list comprehension:
result = [word in plant for plant in syn]
# To get the number of matches, you can sum the resulting list:
sum(result)
Edit: If you have a long list of words to look for, you can just nest two loops:
words_to_search = ["work","spam","foo"]
syn = ["plant.one","plant.two"]
for word in words_to_search_for:
if sum([word in plant for plant in syn]):
print("{} is present in syn".format(word))
Note that you are manipulating Lemma objects and not strings. You might need to check for word in plant.name instead of just word if the object do not implement the [__contains__](https://docs.python.org/2/library/operator.html#operator.__contains__) method. I am not familiar with this library though.
str1 = "this is a example , xxx"
str2 = "example"
target_len = len(str2)
str_start_position = str1.index(str2) #or str1.find(str2)
str_end_position = str_start_position + target_len
you can use str_start_position and str_end_position to get your target substring
I'm looking for a (preferably simple) way to find and order the most common bytes in a python stream element.
e.g.
>>> freq_bytes(b'hello world')
b'lohe wrd'
or even
>>> freq_bytes(b'hello world')
[108,111,104,101,32,119,114,100]
I currently have a function that returns a list in the form list[97] == occurrences of "a". I need that to be sorted.
I figure I basically need to flip the list so list[a] = b --> list[b] = a at the same time removing the repeates.
Try the Counter class in the collections module.
from collections import Counter
string = "hello world"
print ''.join(char[0] for char in Counter(string).most_common())
Note you need Python 2.7 or later.
Edit: Forgot the most_common() method returned a list of value/count tuples, and used a list comprehension to get just the values.
def frequent_bytes(aStr):
d = {}
for char in aStr:
d[char] = d.setdefault(char, 0) + 1
myList = []
for char, frequency in d.items():
myList.append((frequency, char))
myList.sort(reverse=True)
return ''.join(myList)
>>> frequent_bytes('hello world')
'lowrhed '
I just tried something obvious. #kindall's answer rocks, though. :)