I am trying to reverse a list using a recursive function. Unfortunatley I am fairly new to recursion. Is this possible? That is my code thus far
def stringRev (word):
worLen = len(word)
if worLen == 1:
return word
return (word[-1]) + stringRev(word[:-1])
listWord = ["hey", "there", "jim"]
print(stringRev(listWord))
Your problem is that (word[-1]) is a string, not a list. So you are trying to add/concatenate a string and a list. I changed that expression to [word[-1]] to create a list.
>>> def stringRev (word):
... worLen = len(word)
... if worLen == 1:
... return word
... return [word[-1]] + stringRev(word[:-1])
...
>>> listWord = ["hey", "there", "jim"]
>>> print(stringRev(listWord))
['jim', 'there', 'hey']
>>>
PS. It would be helpful if you included the error you received when running your code: TypeError: Can't convert 'list' object to str implicitly
To reverse the order of the elements of the list, change:
return (word[-1]) + stringRev(word[:-1])
to
return [word[-1]] + stringRev(word[:-1])
(note the square brackets).
The problem is that you are trying to concatenate a string (word[-1]) with a list (word[:-1]).
The problem is that your function is expecting a single word, yet you're calling it with a list of words.
If you call it as follows, you'll see that it works just fine:
for word in ["hey", "there", "jim"]:
print(stringRev(word))
Or, if you wish to store the reversed strings in a list:
l = [stringRev(w) for w in ["hey", "there", "jim"]]
The one corner case where your function would fail is the empty string. I don't know whether that's a valid input, so it could be a non-issue (but trivial to fix nonetheless).
If you want it done in Python:
reversed(listWord)
assuming word is a list or a tuple
http://docs.python.org/2/library/functions.html#reversed
And to get a list:
list(reversed(listWord))
should work
But if you want an algorithm, I guess reversed is not your friend !
Related
I’m trying to understand why the str() method doesn’t output the elements in the list when using for loop:
li_1 = ['hi', 'hello', 'howdy']
for i in li_1:
str(i)
Whereas the str() method in the following list comprehension does output the elements:
[str(j) for j in li_1]
Because str does not print anything its just return value so you can store in a variable or directly print returning value using print. Try below code
li_1 = ['hi', 'hello', 'howdy']
for i in li_1:
print(str(i))
or
li_1 = ['hi', 'hello', 'howdy']
[print(str(j)) for j in li_1]
str() method maps input to a string. In your case there is no reason to use it. But if you want to use it you have to first assign the output.
Example:
digit = str(1)
print(digit)
In your case you probably want to print each value from the list like this:
li_1 = [‘hi’, ‘hello’, ‘howdy’]
for word in li_1:
print(word)
Or just:
print(*li_1)
Even if you mix types in your list. The print statement handles this:
li_1 = ["hi", "hello", "howdy", 232]
for word in li_1:
print(word)
Output:
hi
hello
howdy
232
community.
I need to write a function that goes through a string and checks if each word exists in a list, if the word exists in the (Remove list) it should remove that word if not leave it alone.
i wrote this:
def remove_make(x):
a = x.split()
for word in a:
if word in remove: # True
a = a.remove(word)
else:
pass
return a
But it returns back the string with the (Remove) word still in there. Any idea how I can achieve this?
A more terse way of doing this would be to form a regex alternation based on the list of words to remove, and then do a single regex substitution:
inp = "one two three four"
remove = ['two', 'four']
regex = r'\s*(?:' + r'|'.join(remove) + ')\s*'
out = re.sub(regex, ' ', inp).strip()
print(out) # prints 'one three'
You can try something more simple:
import re
remove_list = ['abc', 'cde', 'edf']
string = 'abc is walking with cde, wishing good luck to edf.'
''.join([x for x in re.split(r'(\W+)', string) if x not in remove_list])
And the result would be:
' is walking with , wishing good luck to .'
The important part is the last line:
''.join([x for x in re.split(r'(\W+)', string) if x not in remove_list])
What it does:
You are converthing the string to list of words with re.split(r'(\W+)', string), preserving all the whitespaces and punctuation as list items.
You are creating another list with list comprehension, filtering all the items, which are not in remove_list
You are converting the result list back to string with str.join()
The BNF notation for list comprehensions and a little bit more information on them may be found here
PS: Of course, you may make this a little bit more readable if you break the one-liner into peaces and assign the result of re.split(r'(\W+)', string) to a variable and decouple the join and the comprehension.
You can create a new list without the words you want to remove and then use join() function to concatenate all the words in that list. Try
def remove_words(string, rmlist):
final_list = []
word_list = string.split()
for word in word_list:
if word not in rmlist:
final_list.append(word)
return ' '.join(final_list)
list.remove(x) returns None and modifies the list in-place by removing x it exists inside the list. When you do
a = a.remove(word)
you will be effectively storing None in a and this would give an exception in the next iteration when you again do a.remove(word) (None.remove(word) is invalid), but you don’t get that either since you immediately return after the conditional (which is wrong, you need to return after the loop has finished, outside its scope). This is how your function should look like (without modifying a list while iterating over it):
remove_words = ["abc", ...] # your list of words to be removed
def remove_make(x):
a = x.split()
temp = a[:]
for word in temp:
if word in remove_words: # True
a.remove(word)
# no need of 'else' also, 'return' outside the loop's scope
return " ".join(a)
I have this function here to filter out all words from a list which start with a desired character
new_list = []
def filter_words(word_list, c):
for word in word_list:
if word.startswith(c):
new_list.append(word)
else:
continue
lst = ["Hello", "Cat", "Dog", "House", "Helmet", "Horse", "Bird"]
filter_words(l,"H")
print(new_list)
This work fine - now I'm trying with filter() method
I tried this
list(filter(filter_words, lst)) but I got this error: TypeError: filter_woerter() missing 1 required positional argument: 'c'
so I tried this
list(filter(filter_words, l,'h')) but then got another error: TypeError: filter expected 2 arguments, got 3
So, how do I pass the 2nd argument?
Your filter_words function already takes a list (well, an iterable) as argument and do the filtering by itself, so passing it to filter() makes no sense - filter() expects a function that takes one single element from the iterable and returns a boolean value (this is usually known as a "predicate function"). IOW you'd want:
def word_starts_with(word, letter):
return word.startswith(letter)
and then you'd have to use a lambda as partial application so the letter is fixed:
filter(lambda word: word_starts_with("H"), yourlistofwords)
which FWIW is actually a convoluted way to write:
filter(lambda word: word.startswith("H"), yourlistofwords)
which is more idiomatically written with a list comprehension instead:
[word for word in yourlistofwords if word.startswith("h")]
I am trying to implement an inplace algorithm to remove duplicates from a string in Python.
str1 = "geeksforgeeks"
for i in range(len(str1)):
for j in range(i+1,len(str1)-1):
if str1[i] == str1[j]: //Error Line
str1 = str1[0:j]+""+str1[j+1:]
print str1
In the above code, I am trying to replace the duplicate character with whitespace. But I get IndexError: string index out of range at if str1[i] == str1[j]. Am I missing out on something or is it not the right way?
My expected output is: geksfor
You can do all of this with just a set and a comprehension. No need to complicate things.
str1 = "geeksforgeeks"
seen = set()
seen_add = seen.add
print(''.join(s for s in str1 if not (s in seen or seen_add(s))))
#geksfor
"Simple is better than complex."
~ See PEP20
Edit
While the above is more simple than your answer, it is the most performant way of removing duplicates from a collection the more simple solution would be to use:
from collections import OrderedDict
print("".join(OrderedDict.fromkeys(str1)))
It is impossible to modify strings in-place in Python, the same way that it's impossible to modify numbers in-place in Python.
a = "something"
b = 3
b += 1 # allocates a new integer, 4, and assigns it to b
a += " else" # allocates a new string, " else", concatenates it to `a` to produce "something else"
# then assigns it to a
As already pointed str is immutable, so in-place requirement make no sense.
If you want to get desired output I would do it following way:
str1 = 'geeksforgeeks'
out = ''.join([i for inx,i in enumerate(str1) if str1.index(i)==inx])
print(out) #prints: geksfor
Here I used enumerate function to get numerated (inx) letters and fact that .index method of str, returns lowest possible index of element therefore str1.index('e') for given string is 1, not 2, not 9 and not 10.
Here is a simplified version of unique_everseen from itertools recipes.
from itertools import filterfalse
def unique_everseen(iterable)
seen = set()
see _ add = seen.add
for element in filterfalse(seen.__contains__, iterable):
seen_add(element)
yield element
You can then use this generator with str.join to get the expected output.
str1 = "geeksforgeeks"
new_str1 = ''.join(unique_everseen(str1)) # 'geksfor'
Let's say I have the following list ['house', 'John', 'garden']and a string 'MynameisJohn'. Is there a way in Python to check if any of the words in the list are part of the string even when there are no white spaces? The goal would finally be to have a function which returns the words which are part of the string and maybe something that describes where in the string the words start. So something like this:
def function(list, string):
returns [(word, position in the string)]
I tried some things but essentially nothing works because I don't know how to deal with the missing white spaces... The only method I could think of is checking if any sequence in the string corresponds to one of the words, the problem is I don't know how to implement something like that and it doesn't seem to be very efficient.
I found a question here on StackOverflow which deals with kind of the same problem, but since I have a concrete list to compare the string to, I shouldn't run into the same problem, right?
An IDLE example:
>>> find = ['house', 'John', 'garden']
>>> s = 'MynameisJohn'
>>> results = [item for item in find if item in s]
>>> print( results )
[John]
Explanation:
[item for item in find if item in s] is a list comprehension.
For every item in the list named find, it checks if item in s. This will return True if item is any substring in s. If True, then that item will be in the results list.
For finding position of some string in other string, you can use str.index() method.
This function() accepts list and string and yield words that match and position of the word in the string:
def function(lst, s):
for i in lst:
if i not in s:
continue
yield i, s.index(i)
lst = ['house', 'John', 'garden']
s = 'MynameisJohn'
for word, position in function(lst, s):
print(word, position)
Output:
John 8