index of second repeated character in a string - python

I am trying a hangman code in python. For matching a character of a word , iam using index function to get the location of character.
Ex :word = 'COMPUTER'
user_input = raw_input('Enter a character :') # say 'T; is given here
if user_input in word:
print "\nThe Character %c is present in the word \n" %user_input
word_dict[word.index(user_input)] = user_input
#so the output will looks like
{0: '_', 1: '_', 2: '_', 3: '_', 4: '_', 5: 'T', 6: '_', 7: '_'}
Now , my problems comes when it comes with the repeated character.
# Another example
>>> 'CARTOON'.index('O')
4
For the second 'O', how to get its index. since i have used this 'index' logic, i am looking to continue on this way.

As per the str.index docs, signature looks like this
str.index(sub[, start[, end]])
The second parameter is the starting index to search from. So you can pass the index which you got for the first item + 1, to get the next index.
i = 'CARTOON'.index('O')
print 'CARTOON'.index('O', i + 1)
Output
5
The above code can be written like this
data = 'CARTOON'
print data.index('O', data.index('O') + 1)
You can even have this as a utility function, like this
def get_second_index(input_string, sub_string):
return input_string.index(sub_string, input_string.index(sub_string) + 1)
print get_second_index("CARTOON", "O")
Note: If the string is not found atleast twice, this will throw ValueError.
The more generalized way,
def get_index(input_string, sub_string, ordinal):
current = -1
for i in range(ordinal):
current = input_string.index(sub_string, current + 1)
else:
raise ValueError("ordinal {} - is invalid".format(ordinal))
return current
print get_index("AAABBBCCCC", "C", 4)

A perhaps more pythonic method would be to use a generator, thus avoiding the intermediate array 'found':
def find_indices_of(char, in_string):
index = -1
while True:
index = in_string.find(char, index + 1)
if index == -1:
break
yield index
for i in find_indices_of('x', 'axccxx'):
print i
1
4
5
An alternative would be the enumerate built-in
def find_indices_of_via_enumerate(char, in_string):
return (index for index, c in enumerate(in_string) if char == c)
This also uses a generator.
I then got curious as to perf differences. I'm a year into using python, so I'm only beginning to feel truly knowledgeable. Here's a quick test, with various types of data:
test_cases = [
('x', ''),
('x', 'axxxxxxxxxxxx'),
('x', 'abcdefghijklmnopqrstuvw_yz'),
('x', 'abcdefghijklmnopqrstuvw_yzabcdefghijklmnopqrstuvw_yzabcdefghijklmnopqrstuvw_yzabcdefghijklmnopqrstuvwxyz'),
]
for test_case in test_cases:
print "('{}', '{}')".format(*test_case)
print "string.find:", timeit.repeat(
"[i for i in find_indices_of('{}', '{}')]".format(*test_case),
"from __main__ import find_indices_of",
)
print "enumerate :", timeit.repeat(
"[i for i in find_indices_of_via_enumerate('{}', '{}')]".format(*test_case),
"from __main__ import find_indices_of_via_enumerate",
)
print
Which, on my machine results in these timings:
('x', '')
string.find: [0.6248660087585449, 0.6235580444335938, 0.6264920234680176]
enumerate : [0.9158611297607422, 0.9153609275817871, 0.9118690490722656]
('x', 'axxxxxxxxxxxx')
string.find: [6.01502799987793, 6.077538013458252, 5.997750997543335]
enumerate : [3.595151901245117, 3.5859270095825195, 3.597352981567383]
('x', 'abcdefghijklmnopqrstuvw_yz')
string.find: [0.6462750434875488, 0.6512351036071777, 0.6495819091796875]
enumerate : [2.6581480503082275, 2.6216518878936768, 2.6187551021575928]
('x', 'abcdefghijklmnopqrstuvw_yzabcdefghijklmnopqrstuvw_yzabcdefghijklmnopqrstuvw_yzabcdefghijklmnopqrstuvwxyz')
string.find: [1.2539417743682861, 1.2511990070343018, 1.2702908515930176]
enumerate : [7.837890863418579, 7.791800022125244, 7.9181809425354]
enumerate() method is more expressive, pythonic. Whether or not perf differences matter depends on the actual use cases.

You've asked how to find the second occurrence, and gotten an excellent answer for that, generalized for any specific occurrence. What you'll realize you actually want though is all occurrences at once. Here's a method for that:
def find_characters(word, character):
found = []
last_index = -1
while True:
try:
last_index = word.index(character, last_index+1)
except ValueError:
break
else:
found.append(last_index)
return found

You can use the count method of the strings to find the number of occurrences of the user_input in the string. Then, use the str.index(sub,start) method for each occurrence of the user_input in the word and increment start by 1 each time so that you do not wind up getting the same index each time.
if user_input in word:
count=word.count(user_input)
a=word.index(user_input)
word_dict[word.index(a)]=user_input
for i in range(count-1):
a=word.index(user_input,a+1)
word_dict[word.index(a)]=user_input

This should really be a one-liner if you use filter because if you use index you will be forced to either iterate or use recursion. In this case, there is absolutely no need for either. You can just filter out the values that are relevant to you.
Using filter is easy. An example implementation is the following one-liner:
def f1(w, c):
return zip(* filter(lambda (x,y): x == c, zip(w, range(len(w))) ))[1]
f1('cartoon', 'o') # --> (4, 5)
You can always add error checking as in:
def f1(w, c) :
if c not in w: return ()
else: return zip(* filter(lambda (x,y): x == c, zip(w, range(len(w))) ))[1]
If the character isn't found in the string, you just get an empty tuple. Otherwise, you get all elements that match. If you want something generic, counting on the fact that there will only be one or two instances of a character is not the right way to go about it. For example:
In [18]: f1('supercalifragilisticexpialidocious', 'i')
Out[18]: (8, 13, 15, 18, 23, 26, 30)

Here is another Example.
a="samesame"
po=-1 # for this, po+1 is start from 0
for c in a:
if c=='s': # For example, I chose "S" what I want to find
po = a.index(c,po+1) # if you find first element 'C' then search again in next postion
print(po)

Apologies if this answer is not properly formatted or I've messed up somewhere as I am new here and this is my first post. I have used the following code in my own Hangman games to get the index of multiple repeating letters in a word and has worked great. Hopefully a newcomer will understand this ok.
a = "hangman" #the chosen word
length = len(a) #determines length of chosen word
for i in range(length) #this will loop through the code length number of times
if a[i] == "n": #n is the players guess. Checks if the letter is at index i
po = a.index("n", i) # po gets the index of the letter if previous line is true
print(po) #prints the position/s
Hope this helps someone!

def findcharpos(string, character, position=None):
array = []
index = -1
while True:
try:
index = string.index(character, index+1)
except ValueError:
break
else:
array.append(index)
if position == None and len(array) != 0:
return array
elif position > len(array):
raise ValueError(f"The character {character} does not occur {position}
times in the {string}")
else:
return array[position-1]
return array

msg = 'samesame'
print(msg.index('s', 2)) # prints the index of second 's' in the string.

Related

How do I count up the number of letter pairs in python?

I am making a program in python that count up the number of letter pairs.
For example ------> 'ddogccatppig' will print 3, 'a' will print 0, 'dogcatpig' will print 0, 'aaaa' will print 3, and 'AAAAAAAAAA' will print 9.
My teacher told me to use a for loop to get the i and i+1 index to compare. I do not know how to do this, and I am really confused. My code:
def count_pairs( word ):
pairs = 0
chars = set(word)
for char in chars:
pairs += word.count(char + char)
return pairs
Please help me!!! Thank you.
The for loop is only to iterate through the appropriate values of i, not directly to do the comparison. You need to start i at 0, and iterate through i+1 being the last index in the string. Work this out on paper.
Alternately, use i-1 and i; then you want to start i-1 at 0, which takes less typing:
for i in range(1, len(word)):
if word[i] == word[i-1]:
...
Even better, don't use the counter at all -- make a list of equality results and count the True values:
return sum([word[i] == word[i-1] for i in range(1, len(word))])
This is a bit of a "dirty trick" using the fact that True evaluates as 1 and False as 0.
If you want to loop over indices instead of the actual characters, you can do:
for i in range(len(word)):
# do something with word[i] and/or word[i+1] or word[i-1]
Converting the string to a set first is counterproductive because it removes the ordering and the duplicates, making the entire problem impossible for two different reasons. :)
Here is an answer:
test = "ddogccatppig"
def count_pairs(test):
counter = 0
for i in range(0,len(test)-1):
if test[i] == test[i+1]
counter+=1
return counter
print(count_pairs(test))
Here you iterate through the length of the string (minus 1 because otherwise you will get an index out of bounds exception). Add to a counter if the letter is the same as the one in front and return it.
This is another (similar) way to get the same answer.
def charPairs(word):
word = list(word)
count = 0
for n in range(0, len(word)-1):
if word[n] == word[n+1]:
count +=1
return count
print(charPairs("ddogccatppig"))
print(charPairs("a"))
print(charPairs("dogcatpig"))
print(charPairs("aaaa"))
print(charPairs("AAAAAAAAAA"))

Match integers to letters in Python

I have a string of integers like '32102739' and a dictionary like {32: 'a', '739': 'b', '102': 'c'}. Given that string, I want to return the output string 'acb'.
I am trying
def change(string_, letters, length=1):
if string_[:length] in letters:
return letters[string_[:length]]
else:
return change(string_, letters, length+1)
I am having trouble with checking until the first letter is found, and then continuing to check for the next letter.
Assuming that there is no ambiguity (and that the numbers don't overlap), one could proceed as:
s = '32102739'
d = {'32': 'a', '739': 'b', '102': 'c'}
ret = ''
#start at the beginning of the string
pos, N = 0, len(s)
while pos < N:
#start at the current position pos and keep
#adding characters until a match is found
found = False
for i in range(pos+1, N+1):
#t = int(s[pos:i])
t = s[pos:i]
if t in d:
ret += d[t]
found = True
break
#if no match is found, signal an "invalid" input
if not found: raise ValueError
#update current position in the string
pos = i
print(ret) #gives 'acb'
Your code could work with just a few minor tweaks (at least, it will work for non-overlapping dictionary keys). You just need to change your successful match case so that you recurse on the rest of the string, after translating a prefix. You'll also need to add a base case, so that the recursion stops when the matching fails, or there's nothing left to match.
def change(string_, letters, length=1):
if len(string_) < length: # base case
return "" # you might want to test if string_ is empty and if not, raise an exception
elif string_[:length] in letters:
return letters[string_[:length]] + change(string_[length:], letters) # add recursion
else:
return change(string_, letters, length+1)
I'll end with a note that recursion is not as efficient in Python as it is in some other languages. You could restructure your function to use iteration instead of recursion, and it would probably be more efficient and "Pythonic". ewcz's answer is a good example of such a restructuring.

How to append even and odd chars python

I want to convert all the even letters using one function and all the odd numbers using another function. So, each letter represents 0-25 correspsonding with a-z, so a,c,e,g,i,k,m,o,q,s,u,w,y are even characters.
However, only my even letters are converting correctly.
def encrypt(plain):
charCount = 0
answer=[]
for ch in plain:
if charCount%2==0:
answer.append(pycipher.Affine(7,6).encipher(ch))
else:
answer.append(pycipher.Affine(3,0).encipher(ch))
return ''.join(answer)
You never change charCount in your loop -- So it starts at 0 and stays at 0 which means that each ch will be treated as "even".
Based on your update, you actually want to check if the character is odd or even based on it's "index" in the english alphabet. Having some sort of mapping of characters to numbers is helpful here. You could build it yourself:
alphabet = 'abcde...' # string.ascii_lowercase?
mapping = {k: i for i, k in enumerate(alphabet)}
OR we can use the builtin ord noticing that ord('a') produces an odd result, ord('b') is even, etc.
def encrypt(plain):
answer=[]
for ch in plain:
if ord(ch) % 2 == 1: # 'a', 'c', 'e', ...
answer.append(pycipher.Affine(7,6).encipher(ch))
else: # 'b', 'd', 'f', ...
answer.append(pycipher.Affine(3,0).encipher(ch))
return ''.join(answer)
Your basic approach is to re-encrypt a letter each time you see it. With only 26 possible characters to encrypt, it is probably worth pre-encrypting them, then just performing a lookup for each character in the plain text. While doing that, you don't need to compute the position of each character, because you know you are alternating between even and odd the entire time.
import string
def encrypt(plain):
# True == 1, False == 0
fs = [pycipher.Affine(3,0).encipher,
pycipher.Affine(7,6).encipher]
is_even = True # assuming "a" is even; otherwise, just set this to False
d = dict()
for ch in string.ascii_lowercase:
f = fs[is_even]
d[ch] = f(ch)
is_even = not is_even
return ''.join([d[ch] for ch in plain])
You can also use itertools.cycle to simplify the alternation for you.
def encrypt(plain):
# again, assuming a is even. If not, reverse this list
fs = itertools.cycle([pycipher.Affine(3,0).encipher,
pycipher.Affine(7,6).encipher])
d = dict((ch, f(ch)) for f, ch in zip(fs, string.ascii_lowercase))
return ''.join([d[ch] for ch in plain])
This are my two cents on that. What #mgilson is proposing also works of course but not in the way you specified (in the comments). Try to debug your code in your head after writing it.. Go through the for loop and perform 1-2 iterations to see whether the variables take the values you intended them to. charCount is never reassigned a value. It is always 0. And, yes charCount += 1 would make it change but not in the way you want it to..
def encrypt(plain):
alphabet = 'abcdefghijklmnopqrwstuvwxyz'
answer = ''
for letter in plain:
try:
if alphabet.index(letter.lower()) % 2 == 0:
answer += pycipher.Affine(7, 6).encipher(letter)
else:
answer += pycipher.Affine(3, 0).encipher(letter)
except:
answer += letter
return answer
my_text = 'Your question was not very clear OP'
encripted_text = encrypt(my_text)
Also, i would not use ord(ch) because ord('a') = 97 and not 0 therefore odd instead of even.
Since your notion of even letter is based on the position of a character in the alphabet, you could use ord(), like this:
if ord(ch)%2==0:
Note that ord('a') and ord('A') are both odd, so that would make a go in the else part. If you want the opposite, then just negate the condition:
if ord(ch)%2!=0:

finding the index of the first letter of a sub string in the main string

I am trying to find the index of the first letter of a sub string within the main string. The function acts exactly like the find method of python. I have created a find_chr function that gives me the index of a character in a string and I am using the find_chr to get the index of the substring.
def find_str(s,x):
i=0
if x in s:
return find_chr(s,x[i])
else:
return -1
My problem is that when I am using the string "IS GOING GOING" and substring as "ING", I am getting the index of the first "I", when I am expecting the index of the "I" of "ING". I will appreciate any input about changing the function to get the right index of the first letter of the substring.
In find_str you call find_chr(s,x[i]). This is calling find_chr with only x[i] (the ith part of the substring).
This should fix your problem
def find_chr(s,char):
i=0
step = len(char)
for j in range(len(s)+1):
ch = s[j:j+step]
if ch==char:
return (i)
break
i+=1
return -1
def find_str(s,x):
i=0
if x in s:
return find_chr(s,x)
else:
return -1
You aren't looping through the characters, you only check for i == 0 (i.e. the first character in s). You need to apply a "window" to the string, checking len(s) characters in a row:
def find_str(s, x):
if x in s: # is x present?
for i in range(len(s)): # work through string indices
if s[i:i+len(x)] == x: # does x start at current index?
return i
return -1
This should solve your problem:
def find_str(s, x):
i = 0
while i < len(s):
if s[i:i + len(x)] == x:
return i
else:
i += 1
print find_str('IS GOING GOING', 'ING')
Look up the use of the index function in strings. You will then happily replace all of that code with about 1 line.
Supplying the answer because of the following comments. Seriously though, if one is going to learn python, it is a good exercise to be aware of the methods available for an object.
>>> 'is going going'.index('ing')
5
or more generally
>>> fullstring.index(substring)
This should be marked as the correct answer because it is the simplest and most obviously correct. The complexity of the algorithms offered is way too high for this problem.
If the substring is not in the fullstring, a ValueError exception will be raised. So if you need a function, then it should return the index from a try or -1 (or None) from the except blocks.

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