Lists in Python: Sum of Words with Specific Length - python

I am new to Python and I am not sure what is wrong with my syntax or logic here as this seems fairly straightforward. Do I need to split the words into chars?
Count how many words in a list have length 5.
This is what I have so far:
def countWords(lst):
total=0
for word in lst:
if len(word)==5:
total+=1
return total
Update: There are great answers and explanations here, thank you! Unfortunately, I think the activecode is just not working on this site: https://runestone.academy/runestone/books/published/thinkcspy/Lists/Exercises.html: Question 10.

First you have to fix your indentation, and then you probably want to use another name for your sum variable. I've changed it to found below for you.
def countWords(lst):
found = 0
for word in lst:
if len(word) == 5:
found += 1
return found
Then you'll have to call the function, so
countWords(lst)
where lst is the list of words.

First, indentation is very important in Python, also avoid using built-in names like sum, len etc. Also, function name should be in lower case, with words separated by an underscore. here is the multiline solution
def count_words(lst):
word_count = 0
for word in lst:
if len(word) == 5:
word_count += 1
return word_count
and here is the one-liner solution
def count_words(lst):
return len([word for word in lst if len(word) == 5])

the code correct and will provide you, total no of words having a length of 5.
you don't need to count the individual character of a word as len(str) provide the total no of characters inside the word.
to make this solution more scalable and testable for different length words, you can provide length as an option in the functional argument. setting default word length equals to 5 default and check it inside the function. Adding code for it
def countWords(lst,word_length=5):
total=0
for word in lst:
if len(word)==word_length:
total+=1
return total
if you want solution in single line
def countWords(lst, word_length=5):
return sum(1 for word in lst if len(word)==word_length)

you can do this more directly, by using a list comprehension to find all of the words, and counting from there.
def countWords(lst):
return sum([int(len(word) == 5) for word in lst])
This iterates through all of the words, checking the length, and adding up the resulting Booleans: True is , Falseis 0, by definition. Actually, you don't *need* theint` conversion, but some people prefer it for clarity.

You can also achieve the same using a map + lambda to single out the words in the list of length 5.
lst = ["12345", "123", "1234", "abcde", "123", "1234", "abcde"]
def countWords(lst):
return sum(map(lambda word: len(word) == 5, lst))
print(countWords(lst))
outputs:
3

You must remember that in Python, the indentation is important. In your case, since return sum is not indented, it is considered outside of your countWords() function.
The valid code is:
def countWords(lst):
count=0
for word in lst:
if len(word)==5:
count+=1
return count

It seems to be an indentation problem, check your indentation in the Idle (it makes it more obvious).
Since you are new to python, I will show you some cool ways to do this in python style.
return (len([word for word in lst if len(word) == 5]))
# using the filter function
def isWord(word):
return len(word) == 3
#an_iterator = filter(isWord, lst)
return len(list (filter(isWord, lst)))
# using lambda
#an_iterator = filter(lambda word: len(word), lst)
return len(list (filter(lambda word: len(word), lst)))

Related

Intro to Python - Lists questions

we've started doing Lists in our class and I'm a bit confused thus coming here since previous questions/answers have helped me in the past.
The first question was to sum up all negative numbers in a list, I think I got it right but just want to double check.
import random
def sumNegative(lst):
sum = 0
for e in lst:
if e < 0:
sum = sum + e
return sum
lst = []
for i in range(100):
lst.append(random.randrange(-1000, 1000))
print(sumNegative(lst))
For the 2nd question, I'm a bit stuck on how to write it. The question was:
Count how many words occur in a list up to and including the first occurrence of the word “sap”. I'm assuming it's a random list but wasn't given much info so just going off that.
I know the ending would be similar but no idea how the initial part would be since it's string opposed to numbers.
I wrote a code for a in-class problem which was to count how many odd numbers are on a list(It was random list here, so assuming it's random for that question as well) and got:
import random
def countOdd(lst):
odd = 0
for e in lst:
if e % 2 = 0:
odd = odd + 1
return odd
lst = []
for i in range(100):
lst.append(random.randint(0, 1000))
print(countOdd(lst))
How exactly would I change this to fit the criteria for the 2nd question? I'm just confused on that part. Thanks.
The code to sum -ve numbers looks fine! I might suggest testing it on a list that you can manually check, such as:
print(sumNegative([1, -1, -2]))
The same logic would apply to your random list.
A note about your countOdd function, it appears that you are missing an = (== checks for equality, = is for assignment) and the code seems to count even numbers, not odd. The code should be:
def countOdd(lst):
odd = 0
for e in lst:
if e%2 == 1: # Odd%2 == 1
odd = odd + 1
return odd
As for your second question, you can use a very similar function:
def countWordsBeforeSap(inputList):
numWords = 0
for word in inputList:
if word.lower() != "sap":
numWords = numWords + 1
else:
return numWords
inputList = ["trees", "produce", "sap"]
print(countWordsBeforeSap(inputList))
To explain the above, the countWordsBeforeSap function:
Starts iterating through the words.
If the word is anything other than "sap" it increments the counter and continues
If the word IS "sap" then it returns early from the function
The function could be more general by passing in the word that you wanted to check for:
def countWordsBefore(inputList, wordToCheckFor):
numWords = 0
for word in inputList:
if word.lower() != wordToCheckFor:
numWords = numWords + 1
else:
return numWords
inputList = ["trees", "produce", "sap"]
print(countWordsBeforeSap(inputList, "sap"))
If the words that you are checking come from a single string then you would initially need to split the string into individual words like so:
inputString = "Trees produce sap"
inputList = inputString.split(" ")
Which splits the initial string into words that are separated by spaces.
Hope this helps!
Tom
def count_words(lst, end="sap"):
"""Note that I added an extra input parameter.
This input parameter has a default value of "sap" which is the actual question.
However you can change this input parameter to any other word if you want to by
just doing "count_words(lst, "another_word".
"""
words = []
# First we need to loop through each item in the list.
for item in lst:
# We append the item to our "words" list first thing in this loop,
# as this will make sure we will count up to and INCLUDING.
words.append(item)
# Now check if we have reached the 'end' word.
if item == end:
# Break out of the loop prematurely, as we have reached the end.
break
# Our 'words' list now has all the words up to and including the 'end' variable.
# 'len' will return how many items there are in the list.
return len(words)
lst = ["something", "another", "woo", "sap", "this_wont_be_counted"]
print(count_words(lst))
Hope this helps you understand lists better!
You can make effective use of list/generator comprehensions. Below are fast and memory efficient.
1. Sum of negatives:
print(sum( i<0 for i in lst))
2. Count of words before sap: Like you sample list, it assumes no numbers are there in list.
print(lst.index('sap'))
If it's a random list. Filter strings. Find Index for sap
l = ['a','b',1,2,'sap',3,'d']
l = filter(lambda x: type(x)==str, l)
print(l.index('sap'))
3. Count of odd numbers:
print(sum(i%2 != 0 for i in lst))

Why does 'append' not work as expected in my Python code? [duplicate]

This question already has answers here:
AttributeError: 'NoneType' object has no attribute 'append'
(2 answers)
Closed 6 years ago.
I downloaded Google's Python exercises and this is one of the questions:
Given a list of strings, return the count of the number of strings
where the string length is 2 or more and the first and last chars of
the string are the same
My answer to this is given below:
def match_ends(words):
a=[]
for word in words:
if len(word)>=2 and word[0]==word[-1]:
a=a.append(word)
return len(a)
However, for this list:
words=['aba', 'xyz', 'aa', 'x', 'bbb']
It just returns "1". I don't understand why append did not add all strings that match with if turn.
This is Google's solution:
def match_ends(words):
count = 0
for word in words:
if len(word) >= 2 and word[0] == word[-1]:
count = count + 1
return count
There are two issues here:
an indentation issue:
def match_ends(words):
a=[]
for word in words:
if len(word)>=2 and word[0]==word[-1]:
a=a.append(word)
return len(a)
The return statement is placed inside the for loop, meaning that after only one iteration, you will return an answer (either zero or one). So you can fix this like:
def match_ends(words):
a=[]
for word in words:
if len(word)>=2 and word[0]==word[-1]:
a=a.append(word)
return len(a)
furthermore you assign the result of a.append(word) to a. .append however returns None (actually .append does not return anything, so Python let it automatically return None), so the next iteration, a is not a list anymore and the program would crash. So replace a = a.append(word) with a.append(word):
def match_ends(words):
a=[]
for word in words:
if len(word)>=2 and word[0]==word[-1]:
a.append(word)
return len(a)
Now your program will work. Nevertheless it is useless to store all the matched words because you are only interested in counting them. You better use a counter and increment the counter if you found a match because this requires no additional memory. Google's answer is thus more efficient.
Indent your return statement like this:
for word in words:
if len(word)>=2 and word[0]==word[-1]:
a.append(word)
return len(a)
When you placed it in the level of if it prints the length of the list a that now contains ['a'] as 1 (validated true for the first word that it found to have first and last letter to be the same) and exits since it is a return statement. The loop doesn't validate any other word in your list words.
Edited the answer as I didn't notice the assignment. append function doesn't need an assignment. Thank you #Willem

How to use recursion to find the longest string within multiple lists? (Python)

I'm new here and fairly new to python and I have a question. I had a similar question during my midterm a while back and it has bugged me that I cannot seem to figure it out.
The overall idea was that I had to find the longest string in a nested list. So I came up with my own example to try and figure it out but for some reason I just can't. So I was hoping someone could tell me what I did wrong and how I can go about the problem without using the function max but instead with a for loop. This is my own example with my code:
typing_test = ['The', ['quick', 'brown'], ['fox', ['jumped'], 'over'], 'the', 'lazy', 'dog']
def longest_string (nested_list: 'nested list of strings') -> int:
'''return the longest string within the nested list'''
maximum_length = 0
for word in nested_list:
try:
if type(word) == str:
maximum_length >= len(word)
maximum_length = len(word)
else:
(longest_string((word)))
except:
print('Error')
return maximum_length
My code returns 3 but the highest should be 6 because of the length of jumped I'm not sure if it's going through each list and checking each strings length. In short I don't think it is replacing/updating the longest string. So if someone can tell me what I'm doing wrong or how to fix my example I would greatly appreciate it. And thank you very much in advance.
There's a few problems in your code:
You need to store the value of the recursive call (maximum_length = (longest_string((word))))
You need to replace the current max value if the length of the word is greater (not less as in your code). There's also no if in this part of your code.
This is the modified code of your function (with minimal modifications to make it work):
def longest_string (nested_list):
maximum_length = 0
for word in nested_list:
try:
if type(word) == str:
if maximum_length < len(word):
maximum_length = len(word)
else:
maximum_length = longest_string((word))
except:
print('Error')
return maximum_length
You are going to use the recursion to figure out the longest string in a nested list.
The recursion should be able to have an end condition. For your question, I would like to put "If the parameter is a str".
Then, suppose the parameter will always be str or list, and we do not consider other boundary conditions, the code will be like:
def longest_string(p):
if type(p) == str:
return len(p) # Return the length of the str.
return max([longest_string(x) for x in p])
You can use a List Comprehension:
def longest(lst):
return max([0]+[i for i in lst if isinstance(i,int)]+
[len(s) for s in lst if isinstance(s,str)]+
[longest(L) for L in lst if isinstance(L,list)])
The [0] is needed for an empty list including at the top level.

Find Longest Word Not Working

So I was exploring on coderbyte.com and one of the challenges is to find the longest word in a string. My code to do so is the following:
def LongestWord(sen):
current="";
currentBest=0
numberOfLettersInWord=0
longestWord=0
temp=sen.split()
for item in temp:
listOfCharacters=list(item)
for currentChar in listOfCharacters:
if currentChar.isalpha():
numberOfLettersInWord+=1
if numberOfLettersInWord>longestWord:
longestWord=numberOfLettersInWord
numberOfLettersInWord=0
currentBest=item
z = list(currentBest)
x=''
for item in z:
if item.isalpha(): x+=item
return x
testCase="a confusing /:sentence:/ this"
print LongestWord(testCase)
when testCase is "a confusing /:sentence:/"
The code returns confusing, which is the correct answer. But when the test case is the one in the current code, my code is returning 'this' instead of 'confusing'
Any ideas as to why this is happening?
I know that this is not the answer to your question, but this is how I would calculate the longest word. And not sharing it, wouldn't help you, either:
import re
def func(text: str) -> str:
words = re.findall(r"[\w]+", text)
return max(words, key=len)
print(func('a confusing /:sentence:/ this'))
Let me suggest another approach, which is more modular and more Pythonic.
Let's make a function to measure word length:
def word_length(w):
return sum(ch.isalpha() for ch in w)
So it will count (using sum()) how many characters there are for which .isalpha() is True:
>>> word_length('hello!!!')
5
>>> word_length('/:sentence:/')
8
Now, from a list of words, create a list of lengths. This is easily done with map():
>>> sen = 'a confusing /:sentence:/ this'.split()
>>> map(word_length, sen)
[1, 9, 8, 4]
Another builtin useful to find the maximum value in a list is max():
>>> max(map(word_length, sen))
9
But you want to know the word which maximizes the length, which in mathematical terms is called argument of the maximum.
To solve this, zip() the lengths with the words, and get the second argument found by max().
Since this is useful in many cases, make it a function:
def arg_max(func, values):
return max(zip(map(func, values), values))[1]
Now the longest word is easily found with:
>>> arg_max(word_length, sen)
'confusing'
Note: PEP-0008 (Style Guide for Python Code) suggests that function names be lower case and with words separated by underscore.
You loop through the words composing the sentence. However, numberOfLettersInWord is never reseted so it keeps increasing while you iterate among the words.
You have to set the counter to 0 each time you start a new word.
for item in temp:
numberOfLettersInWord = 0
It solves your issue as you can see: https://ideone.com/y1cmHX
Here's a little function I just wrote that will return the longest word, using a regular expression to remove non alpha-numeric characters
import re
def longest_word(input):
words = input.split()
longest = ''
for word in words:
word = re.sub(r'\W+', '', word)
if len(word) > len(longest):
longest = word
return longest
print(longest_word("a confusing /:sentence:/ this"))

Reverse a string without using reversed() or [::-1]?

I came across a strange Codecademy exercise that required a function that would take a string as input and return it in reverse order. The only problem was you could not use the reversed method or the common answer here on stackoverflow, [::-1].
Obviously in the real world of programming, one would most likely go with the extended slice method, or even using the reversed function but perhaps there is some case where this would not work?
I present a solution below in Q&A style, in case it is helpful for people in the future.
You can also do it with recursion:
def reverse(text):
if len(text) <= 1:
return text
return reverse(text[1:]) + text[0]
And a simple example for the string hello:
reverse(hello)
= reverse(ello) + h # The recursive step
= reverse(llo) + e + h
= reverse(lo) + l + e + h
= reverse(o) + l + l + e + h # Base case
= o + l + l + e + h
= olleh
Just another option:
from collections import deque
def reverse(iterable):
d = deque()
d.extendleft(iterable)
return ''.join(d)
Use reversed range:
def reverse(strs):
for i in xrange(len(strs)-1, -1, -1):
yield strs[i]
...
>>> ''.join(reverse('hello'))
'olleh'
xrange or range with -1 step would return items in reversed order, so we need to iterate from len(string)-1 to -1(exclusive) and fetch items from the string one by one.
>>> list(xrange(len(strs) -1, -1 , -1))
[4, 3, 2, 1, 0] #iterate over these indexes and fetch the items from the string
One-liner:
def reverse(strs):
return ''.join([strs[i] for i in xrange(len(strs)-1, -1, -1)])
...
>>> reverse('hello')
'olleh'
EDIT
Recent activity on this question caused me to look back and change my solution to a quick one-liner using a generator:
rev = ''.join([text[len(text) - count] for count in xrange(1,len(text)+1)])
Although obviously there are some better answers here like a negative step in the range or xrange function. The following is my original solution:
Here is my solution, I'll explain it step by step
def reverse(text):
lst = []
count = 1
for i in range(0,len(text)):
lst.append(text[len(text)-count])
count += 1
lst = ''.join(lst)
return lst
print reverse('hello')
First, we have to pass a parameter to the function, in this case text.
Next, I set an empty list, named lst to use later. (I actually didn't know I'd need the list until I got to the for loop, you'll see why it's necessary in a second.)
The count variable will make sense once I get into the for loop
So let's take a look at a basic version of what we are trying to accomplish:
It makes sense that appending the last character to the list would start the reverse order. For example:
>>lst = []
>>word = 'foo'
>>lst.append(word[2])
>>print lst
['o']
But in order to continue reversing the order, we need to then append word[1] and then word[0]:
>>lst.append(word[2])
>>lst.append(word[1])
>>lst.append(word[0])
>>print lst
['o','o','f']
This is great, we now have a list that has our original word in reverse order and it can be converted back into a string by using .join(). But there's a problem. This works for the word foo, it even works for any word that has a length of 3 characters. But what about a word with 5 characters? Or 10 characters? Now it won't work. What if there was a way we could dynamically change the index we append so that any word will be returned in reverse order?
Enter for loop.
for i in range(0,len(text)):
lst.append(text[len(text)-count])
count += 1
First off, it is necessary to use in range() rather than just in, because we need to iterate through the characters in the word, but we also need to pull the index value of the word so that we change the order.
The first part of the body of our for loop should look familiar. Its very similar to
>>lst.append(word[..index..])
In fact, the base concept of it is exactly the same:
>>lst.append(text[..index..])
So what's all the stuff in the middle doing?
Well, we need to first append the index of the last letter to our list, which is the length of the word, text, -1. From now on we'll refer to it as l(t) -1
>>lst.append(text[len(text)-1])
That alone will always get the last letter of our word, and append it to lst, regardless of the length of the word. But now that we have the last letter, which is l(t) - 1, we need the second to last letter, which is l(t) - 2, and so on, until there are no more characters to append to the list. Remember our count variable from above? That will come in handy. By using a for loop, we can increment the value of count by 1 through each iteration, so that the value we subtract by increases, until the for loop has iterated through the entire word:
>>for i in range(0,len(text)):
..
.. lst.append(text[len(text)-count])
.. count += 1
Now that we have the heart of our function, let's look at what we have so far:
def reverse(text):
lst = []
count = 1
for i in range(0,len(text)):
lst.append(text[len(text)-count])
count += 1
We're almost done! Right now, if we were to call our function with the word 'hello', we would get a list that looks like:
['o','l','l','e','h']
We don't want a list, we want a string. We can use .join for that:
def reverse(text):
lst = []
count = 1
for i in range(0,len(text)):
lst.append(text[len(text)-count])
count += 1
lst = ''.join(lst) # join the letters together without a space
return lst
And that's it. If we call the word 'hello' on reverse(), we'd get this:
>>print reverse('hello')
olleh
Obviously, this is way more code than is necessary in a real life situation. Using the reversed function or extended slice would be the optimal way to accomplish this task, but maybe there is some instance when it would not work, and you would need this. Either way, I figured I'd share it for anyone who would be interested.
If you guys have any other ideas, I'd love to hear them!
Only been coding Python for a few days, but I feel like this was a fairly clean solution. Create an empty list, loop through each letter in the string and append it to the front of the list, return the joined list as a string.
def reverse(text):
backwardstext = []
for letter in text:
backwardstext.insert(0, letter)
return ''.join(backwardstext)
I used this:
def reverse(text):
s=""
l=len(text)
for i in range(l):
s+=text[l-1-i]
return s
Inspired by Jon's answer, how about this one
word = 'hello'
q = deque(word)
''.join(q.pop() for _ in range(len(word)))
This is a very interesting question, I will like to offer a simple one
liner answer:
>>> S='abcdefg'
>>> ''.join(item[1] for item in sorted(enumerate(S), reverse=True))
'gfedcba'
Brief explanation:
enumerate() returns [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e'), (5, 'f'), (6, 'g')]. The indices and the values.
To reverse the values, just reverse sort it by sorted().
Finally, just put it together back to a str
I created different versions of how to reverse a string in python in my repo:
https://github.com/fedmich/Python-Codes/tree/master/Reverse%20a%20String
You can do it by using list-comprehension or lambda technique:
# Reverse a string without using reverse() function
s = 'Federico';
li = list( s ) #convert string to list
ret = [ li[i-1] for i in xrange(len(li),0,-1) ] #1 liner lambda
print ( "".join( ret ) )
or by doing a backward for loop
# Reverse a string without using reverse() function
s = 'Federico';
r = []
length = len(s)
for i in xrange(length,0,-1):
r.append( s[ i - 1] )
print ( "".join(r) )
reduce(lambda x, y : y + x, "hello world")
A golfed version: r=lambda x:"".join(x[i] for i in range(len(x-1),-1,-1)).
i just solved this in code academy and was checking my answers and ran across this list. so with a very limited understanding of python i just did this and it seamed to work.
def reverse(s):
i = len(s) - 1
sNew = ''
while i >= 0:
sNew = sNew + str(s[i])
i = i -1
return sNew
def reverse(s):
return "".join(s[i] for i in range(len(s)-1, -1, -1))
Blender's answer is lovely, but for a very long string, it will result in a whopping RuntimeError: maximum recursion depth exceeded. One might refactor the same code into a while loop, as one frequently must do with recursion in python. Obviously still bad due to time and memory issues, but at least will not error.
def reverse(text):
answer = ""
while text:
answer = text[0] + answer
text = text[1:]
return answer
Today I was asked this same exercise on pen&paper, so I come up with this function for lists:
def rev(s):
l = len(s)
for i,j in zip(range(l-1, 0, -1), range(l//2)):
s[i], s[j] = s[j], s[i]
return s
which can be used with strings with "".join(rev(list("hello")))
This is a way to do it with a while loop:
def reverse(s):
t = -1
s2 = ''
while abs(t) < len(s) + 1:
s2 = s2 + s[t]
t = t - 1
return s2
I have also just solved the coresponding exercise on codeacademy and wanted to compare my approach to others. I have not found the solution I used so far, so I thought that I sign up here and provide my solution to others. And maybe I get a suggestion or a helpful comment on how to improve the code.
Ok here it goes, I did not use any list to store the string, instead I have just accessed the string index. It took me a bit at first to deal with the len() and index number, but in the end it worked :).
def reverse(x):
reversestring = ""
for n in range(len(str(x))-1,-1, -1):
reversestring += x[n]
return reversestring
I am still wondering if the reversestring = "" could be solved in a more elegant way, or if it is "bad style" even, but i couldn't find an answer so far.
def reverse(text):
a=""
l=len(text)
while(l>=1):
a+=text[l-1]
l-=1
return a
i just concatenated the string a with highest indexes of text (which keeps on decrementing by 1 each loop).
All I did to achieve a reverse string is use the xrange function with the length of the string in a for loop and step back per the following:
myString = "ABC"
for index in xrange(len(myString),-1):
print index
My output is "CBA"
You can simply reverse iterate your string starting from the last character. With python you can use list comprehension to construct the list of characters in reverse order and then join them to get the reversed string in a one-liner:
def reverse(s):
return "".join([s[-i-1] for i in xrange(len(s))])
if you are not allowed to even use negative indexing you should replace s[-i-1] with s[len(s)-i-1]
You've received a lot of alternative answers, but just to add another simple solution -- the first thing that came to mind something like this:
def reverse(text):
reversed_text = ""
for n in range(len(text)):
reversed_text += text[-1 - n]
return reversed_text
It's not as fast as some of the other options people have mentioned(or built in methods), but easy to follow as we're simply using the length of the text string to concatenate one character at a time by slicing from the end toward the front.
def reverseThatString(theString):
reversedString = ""
lenOfString = len(theString)
for i,j in enumerate(theString):
lenOfString -= 1
reversedString += theString[lenOfString]
return reversedString
This is my solution using the for i in range loop:
def reverse(string):
tmp = ""
for i in range(1,len(string)+1):
tmp += string[len(string)-i]
return tmp
It's pretty easy to understand. I start from 1 to avoid index out of bound.
Here's my contribution:
def rev(test):
test = list(test)
i = len(test)-1
result = []
print test
while i >= 0:
result.append(test.pop(i))
i -= 1
return "".join(result)
You can do simply like this
def rev(str):
rev = ""
for i in range(0,len(str)):
rev = rev + str[(len(str)-1)-i]
return rev
Here is one using a list as a stack:
def reverse(s):
rev = [_t for _t in s]
t = ''
while len(rev) != 0:
t+=rev.pop()
return t
Try this simple and elegant code.
my_string= "sentence"
new_str = ""
for i in my_string:
new_str = i + new_str
print(new_str)
you have got enough answer.
Just want to share another way.
you can write a two small function for reverse and compare the function output with the given string
var = ''
def reverse(data):
for i in data:
var = i + var
return var
if not var == data :
print "No palindrome"
else :
print "Palindrome"
Not very clever, but tricky solution
def reverse(t):
for j in range(len(t) // 2):
t = t[:j] + t[- j - 1] + t[j + 1:- j - 1] + t[j] + t[len(t) - j:]
return t
Pointfree:
from functools import partial
from operator import add
flip = lambda f: lambda x, y: f(y, x)
rev = partial(reduce, flip(add))
Test:
>>> rev('hello')
'olleh'

Categories