Here is the code I have written to find duplicate characters and then replace them by ')' and original characters by '(' in a string and it should ignore capitalization.
def duplicate_finder(word):
word1 = word.lower();
w = list(word1);
w1 = '';
for i in range(0, len(word1)):
if ([v in word1.replace(w[i], '') for v in w[i]]==[True]):
w1 += ')';
else:
w1 += '(';
return (w1)
But this function always returns me '((((((...((' [till the number of characters in the input string]. Can someone please point me the fault in my code!!!
Thanks in advance.
The loop you run always gives False because: word1.replace(w[i],'') replaces all instances of w[i] in word1. So when you look for v in word1.replace(w[i],''), it doesn't find any as you relaced all of them. This calls w1 += '(' everytime!
You can do :
>>> def duplicate_finder(word):
... word1 = word.lower();
... w = list(word1);
... w1 = '';
... for i in range(0, len(word1)):
... if ([v in word1[:i]+word1[i+1:] for v in w[i]]==[True]):
... w1 += ')';
... else:
... w1 += '(';
... return (w1)
...
>>> duplicate_finder('hello')
'(())('
I would do it some other way, involving dictionary keeping counts to get true O(n) algo
Here's one way (assuming I understand the question):
def duplicate_finder(word):
word1 = word.lower();
for c in word1:
# If more that one occurence of c
if 1 != word1.count(c):
# Replace all c with (
word1 = word1.replace(c, '(')
# Only one occurence
else:
word1 = word1.replace(c, ')')
return word1
def duplicate_finder(word):
word = word.lower()
l = len(word)
for i in range(l):
index = word.find(word[i], i+1)
if index != -1 and word[i] !=')':
word = word.replace(word[i], '(', 1)
word = word.replace(word[index], ')', 1)
return (word)
Test:
I gave input as "Sanjana"
Output screenshot with steps of replacement
It resulted in s((j))a
Note:
word[i] != ')' check is necessary as there is a possibility of replacement of already existing ) in the unseen segment of the string, and thus can produce weird output
Edit
def duplicate_finder(word):
word = word.lower()
l = len(word)
for i in range(l):
index = word.find(word[i], i+1)
if word[i] not in [')', '('] :
if index != -1:
word = word.replace(word[i], ')')
else:
word = word.replace(word[i], '(')
return (word)
def duplicate_finder(word):
word1 = word.lower();
w1 = '';
length = len(word1)
for i in range(0, length):
w2 = word1[i]
if(word1[i] != ")"):
word1 = word1.replace(word1[i],"(",1)
for v in range(i+1,length):
if(word1[v] != ")" and word1[v] != "("):
if (word1[v] == w2):
word1 = word1.replace(w2,")")
return (word1)
Here is a possible solution:
def duplicate_finder(word):
word1 = word.lower()
w1 = ''
found_chars= set([])
for c in word1:
if c in found_chars:
w1+=')'
else:
found_chars.add(c)
w1+='('
print w1
#Satya, I have used the concept of Counter container of collections module in Python to solve your problem.
A Counter is a subclass of dict. Therefore it is an unordered collection where elements and their respective count are stored as dictionary. This is equivalent to bag or multiset of other languages.
Note: Do not forget to check the References for Counter which is give at very bottom of this answer and comment if find any difficulty.
Have a look at the below code.
"""
StkOvrFlw link: https://stackoverflow.com/questions/50485559/how-to-make-a-function-to-find-duplicacy-in-a-character-string
Aim: [
'1. Here, original character means the character which '
'is first time appearing in the string'
'2. Replacing original character with => ('
'3. If there are more occurences of original character'
then replace them with => )'
]
References: http://www.pythonforbeginners.com/collection/python-collections-counter
"""
from collections import Counter
# Code
def duplicate_finder(word):
word = word.lower()
i = 1;
for ch, count in Counter(word).items():
# print '(', i, ') Original character: \'', ch, '\'with', count - 1, 'more occurence(s)'
if count == 1:
word = word.replace(ch, '(') # Only 1 occurence of original character
else:
l = list(word)
l[word.find(ch)] = '(' # Replace original character with (
word = ''.join(l)
word = word.replace(ch, ')') # Replace other occurences of original character with )
# print 1, 'occurence of \'', ch, '\' replaced with \'(\' and remaining ', count - 1, ' occurence(s) with \')\''
# print 'Iteration ', i, ' gives: ', word, '\n'
i += 1
return word
# Test case 1
print "I/P: abaccccsgfsyetgdggdh"
print "O/P: ", duplicate_finder('abaccccsgfsyetgdggdh')
"""
I/P: abaccccsgfsyetgdggdh
O/P: (()()))((()((()()))(
"""
# Test case 2
print "\nI/P: AAABBBCCC34519543absd67das1729"
print "O/P: ", duplicate_finder('AAABBBCCC34519543absd67das1729')
"""
I/P: AAABBBCCC34519543absd67das1729
O/p: ())())())((((()))))(((()))))()
"""
References: You can find nice articles on Counter container of Python at:
http://www.pythonforbeginners.com/collection/python-collections-counter and
https://www.geeksforgeeks.org/counters-in-python-set-1/
# Find duplicate characters in a string by following conditions:
# - the first (original) character will replaced by '('
# - all others matches will replaced by ')'
# - all in a string with ignore capitalization
def duplicate_finder(word):
s = word.lower()
for ch in s:
if s.count(ch) > 1: # is there more copies of this one character ?
s = s.replace(ch, '(', 1).replace(ch, ')') # the first match will replaced by '(' character, and then all other matches will replaced by ')' character
return s
print 'result: ' + duplicate_finder('hello world') # result: he()( w)r)d
# 0123456789A 0123456789A
New code (by comment from Satya - at 23:26):
# Find duplicate characters in the string by following conditions:
# - all single characters will replaced by '('
# - all multiple characters (duplicates) will replaced by ')'
# - input string must ignore capitalization
def duplicate_finder(word):
s = word.lower()
for ch in s:
if s.count(ch) > 1: # is there more copies of this one character ?
s = s.replace(ch, ')' ) # replace all matched ch by ')'
else:
s = s.replace(ch, '(', 1) # replace this one matched ch by '(' - there's only one character
return s
print 'result: ' + duplicate_finder('hello world') # result: (()))(()()(
# 0123456789A 0123456789A
Related
This question already has answers here:
Split a string at uppercase letters
(22 answers)
Closed 2 years ago.
I am trying to make a script that will accept a string as input in which all of the words are run together, but the first character of each word is uppercase. It should convert the string to a string in which the words are separated by spaces and only the first word starts with an uppercase letter.
For Example (The Input):
"StopWhateverYouAreDoingInterestingIDontCare"
The expected output:
"Stop whatever you are doing interesting I dont care"
Here is the one I wrote so far:
string_input = "StopWhateverYouAreDoingInterestingIDontCare"
def organize_string():
start_sentence = string_input[0]
index_of_i = string_input.index("I")
for i in string_input[1:]:
if i == "I" and string_input[index_of_i + 1].isupper():
start_sentence += ' ' + i
elif i.isupper():
start_sentence += ' ' + i.lower()
else:
start_sentence += i
return start_sentence
While this takes care of some parts, I am struggling with differentiating if the letter "I" is single or a whole word. Here is my output:
"Stop whatever you are doing interesting i dont care"
Single "I" needs to be uppercased, while the "I" in the word "Interesting" should be lowercased "interesting".
I will really appreciate all the help!
A regular expression will do in this example.
import re
s = "StopWhateverYouAreDoingInterestingIDontCare"
t = re.sub(r'(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z])', ' ', s)
Explained:
(?<=[a-z])(?=[A-Z]) - a lookbehind for a lowercase letter followed by a lookahead uppercase letter
| - (signifies or)
(?<=[A-Z])(?=[A-Z]) - a lookbehind for a uppercase letter followed by a lookahead uppercase letter
This regex substitutes a space when there is a lowercase letter followed by an uppercase letter, OR, when there is an uppercase letter followed by an uppercase letter.
UPDATE: This doesn't correctly lowercase the words (with the exception of I and the first_word)
UPDATE2: The fix to this is:
import re
s = "StopWhateverYouAreDoingInterestingIDontCare"
first_word, *rest = re.split(r'(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z])', s)
rest = [word.lower() if word != 'I' else word for word in rest]
print(first_word, ' '.join(rest))
Prints:
Stop whatever you are doing interesting I dont care
Update 3: I looked at why your code failed to correctly form the sentence (which I should have done in the first place instead of posting my own solution :-)).
Here is the corrected code with some remarks about the changes.
string_input = "StopWhateverYouAreDoingInterestingIDontCare"
def organize_string():
start_sentence = string_input[0]
#index_of_i = string_input.index("I")
for i, char in enumerate(string_input[1:], start=1):
if char == "I" and string_input[i + 1].isupper():
start_sentence += ' ' + char
elif char.isupper():
start_sentence += ' ' + char.lower()
else:
start_sentence += char
return start_sentence
print(organize_string())
!. I commented out the line index_of_i = string_input.index("I") as it doesn't do what you need (it finds the index of the first capital I and not an I that should stand alone (it finds the index of the I in Interesting instead of the IDont further in the string_input string). It is not a correct statement.
for i, char in enumerate(string_input[1:], 1) enumerate states the index of the letters in the string starting at 1 (since string_input[1:] starts at index 1 so they are in sync). i is the index of a letter in string_input.
I changed the i's to char to make it clearer that char is the character. Other than these changes, the code stands as you wrote it.
Now the program gives the correct output.
string_input = "StopWhateverYouAreDoingInterestingIDontCare"
counter = 1
def organize_string():
global counter
start_sentence = string_input[0]
for i in string_input[1:]:
if i == "I" and string_input[counter+1].isupper():
start_sentence += ' ' + i
elif i.isupper():
start_sentence += ' ' + i.lower()
else:
start_sentence += i
counter += 1
print(start_sentence)
organize_string()
I made some changes to your program. I used a counter to check the index position. I get your expected output:
Stop whatever you are doing interesting I dont care
s = 'StopWhateverYouAreDoingInterestingIDontCare'
ss = ' '
res = ''.join(ss + x if x.isupper() else x for x in s).strip(ss).split(ss)
sr = ''
for w in res:
sr = sr + w.lower() + ' '
print(sr[0].upper() + sr[1:])
output
Stop whatever you are doing interesting i dont care
I hope this will work fine :-
string_input = "StopWhateverYouAreDoingInterestingIDontCare"
def organize_string():
i=0
while i<len(string_input):
if string_input[i]==string_input[i].upper() and i==0 :
print(' ',end='')
print(string_input[i].upper(),end='')
elif string_input[i]==string_input[i].upper() and string_input[i+1]==string_input[i+1].upper():
print(' ',end='')
print(string_input[i].upper(),end='')
elif string_input[i]==string_input[i].upper() and i!=0:
print(' ',end='')
print(string_input[i].lower(),end='')
if string_input[i]!=string_input[i].upper():
print(string_input[i],end='')
i=i+1
organize_string()
Here is one solution utilising the re package to split the string based on the upper case characters. [Docs]
import re
text = "StopWhateverYouAreDoingInterestingIDontCare"
# Split text by upper character
text_splitted = re.split('([A-Z])', text)
print(text_splitted)
As we see in the output below the separator (The upper case character) and the text before and after is kept. This means that the upper case character is always followed by the rest of the word. The empty first string originates from the first upper case character, which is the first separator.
# Output of print
[
'',
'S', 'top',
'W', 'hatever',
'Y', 'ou',
'A', 're',
'D', 'oing',
'I', 'nteresting',
'I', '',
'D', 'ont',
'C', 'are'
]
As we have seen the first character is always followed by the rest of the word. By combining the two we have the splitted words. This also allows us to easily handle your special case with the I
# Remove first character because it is always empty if first char is always upper
text_splitted = text_splitted[1:]
result = []
for i in range(0, len(text_splitted), 2):
word = text_splitted[i]+text_splitted[i+1]
if (i > 0) and (word != 'I') :
word = word.lower()
result.append(word)
result = ' '.join(result)
split the sentence into individual words. If you find the word "I" in this list, leave it alone. Leave the first word alone. All of the other words, you cast to lower case.
You have to use some string manipulation like this:
output=string_input[0]
for l in string_input[1:]:
if l.islower():
new_s+=l
else:
new_s+=' '+l.lower()
print(output)
Need to remove all excess white spaces in a string, including ones at the beginning and end. I cannot use the split function. Only if and while statements. I have this so far, but every time i run it, it only returns the input the exact same way.
def cleanstring(S):
i=0
startpos=0
endpos=0
end=-1
word=0
#find position of first letter
while S[i]==(" "):
i=i+0
startpos=i
#find last letter
while (S[end]==(" ")):
end=end-1
endpos=S[len(S)-end]
#make first letter found the first letter in the string
if S[i]!=(" "):
word=S[i]
#start between startpos and endpos to find word
while (i<endpos) and (i>startpos):
while S[i]!=(" "):
word=word+S[i]
if S[i]==(" "):
if (S[i+1]==("")) or (S[i-1]==(" ")):
word=word+(" ")
else:
word=word+(" ")
#return the word
print(word)
Input=[" Hello to the world "]
Concat as you go to a temp string, if you hit a whitespace char check if the temp string is not empty, if not yield it and reset the temp string.
s = " Hello to the world "
def split(s):
temp_s = ""
for ch in s:
if ch.isspace():
if temp_s:
yield temp_s
temp_s = ""
else:
temp_s += ch
if temp_s:
yield temp_s
Output:
In [5]: s = " Hello to the world "
In [6]: list(split(s))
Out[6]: ['Hello', 'to', 'the', 'world']
In [7]: s = " Hello\tto\r\nthe world "
In [8]: list(split(s))
Out[8]: ['Hello', 'to', 'the', 'world']
In [10]: list(split(s))
Out[10]: ['Hello', 'world']
In [11]: s = "Hello"
In [12]: list(split(s))
Out[12]: ['Hello']
Obviously if needed you can change the for's to a while loops.
If you call your cleanstring function with a string with a space in it, this will cause an infinite loop:
while S[i]==(" "):
i=i+0
startpos=i
Since you are adding zero to i, it will never change. You should increment it by 1, which can be done like this:
i += 1
which is short hand for
i = i + 1
However, Input is not even a string, but a list with a string in it. You should change the input expression to this
Input = " Hello to the world "
The square brackets you have are making it a list with a string in it.
Using for:
def cleanstring(str_in):
str_out = ''
last_char = None
for cur_char in str_in:
str_out += '' if last_char == ' ' and cur_char ==' ' else cur_char
last_char = cur_char
return str_out
Using while:
def cleanstring(str_in):
str_out = ''
last_char = None
index = 0
while str_in[index:index+1]:
cur_char = str_in[index:index+1]
str_out += '' if last_char == ' ' and cur_char ==' ' else cur_char
last_char = cur_char
index+=1
return str_out
If the last character and current are spaces then do not append a space.
We assume that spaces are the only whitespace concerned. Otherwise this is a solution for sets of whitespace:
def cleanstring(str_in):
str_out = ''
last_char = None
index = 0
whitespace = [' ','\t','\n','\r','\f','\v']
while str_in[index:index+1]:
a = str_in[index:index+1]
str_out += '' if last_char in whitespace and a in whitespace else a
last_char = a
index+=1
return str_out
That removes all whitespace aside from the first detected entry, however if we want to remove whitespace that is similar to adjacent whitespace and leave the first detected instance:
def cleanstring(str_in):
str_out = ''
last_char = None
index = 0
whitespace = [' ','\t','\n','\r','\f','\v']
while str_in[index:index+1]:
a = str_in[index:index+1]
str_out += '' if last_char == a and a in whitespace else a
last_char = a
index+=1
return str_out
If you are concerned about the use of in, it can be replaced with (using last instance of cleanstring as example):
def cleanstring(str_in):
def is_whitespace_in(char):
whitespace = [' ','\t','\n','\r','\f','\v']
local_index = 0
while whitespace[local_index:local_index+1]:
a = whitespace[local_index:local_index+1][0]
if a[0] == char:
return True
local_index+=1
return False
str_out = ''
last_char = None
index = 0
while str_in[index:index+1]:
a = str_in[index:index+1]
str_out += '' if last_char == a and is_whitespace_in(a) else a
last_char = a
index+=1
return str_out
Whitespace of the last examples follows from Cython re's \s definition:
\s Matches any whitespace character; equivalent to [ \t\n\r\f\v] in
bytes patterns or string patterns with the ASCII flag.
Lines 73-74
I know this may not be the most Pythonic or PEP8 compliant, please feel free to edit this.
Just use the string.strip() method.
Is this kind of homework or something?
If you can't use 'for', only 'if' and 'while', then I'd use a counter and check for each char in your string.
def clean(input):
idx = 0
out = input[idx]
while idx < len(input):
if input[idx] != out[-1] or input[idx] != ' ':
out += input[idx]
idx+=1
return out
Of course, it's not the full solution, but you get the idea.
Please read the comment below.
TABLE = str.maketrans('','',' \n\r\t\f')
def clrstr(inp):
return inp.translate(TABLE)
However, it does not help much if you are learning while and for loops.
What are other ways to split a string without using the split() method? For example, how could ['This is a Sentence'] be split into ['This', 'is', 'a', 'Sentence'] without the use of the split() method?
sentence = 'This is a sentence'
split_value = []
tmp = ''
for c in sentence:
if c == ' ':
split_value.append(tmp)
tmp = ''
else:
tmp += c
if tmp:
split_value.append(tmp)
You can use regular expressions if you want:
>>> import re
>>> s = 'This is a Sentence'
>>> re.findall(r'\S+', s)
['This', 'is', 'a', 'Sentence']
The \S represents any character that isn't whitespace, and the + says to find one or more of those characters in a row. re.findall will create a list of all strings that match that pattern.
But, really, s.split() is the best way to do it.
A recursive version, breaking out the steps in detail:
def my_split(s, sep=' '):
s = s.lstrip(sep)
if sep in s:
pos = s.index(sep)
found = s[:pos]
remainder = my_split(s[pos+1:])
remainder.insert(0, found)
return remainder
else:
return [s]
print my_split("This is a sentence")
Or, the short, one-line form:
def my_split(s, sep=' '):
return [s[:s.index(sep)]] + my_split(s[s.index(sep)+1:]) if sep in s else [s]
Starting with a list of strings, if you would like to split these strings there are a couple ways to do so depending on what your desired output is.
Case 1: One list of strings (old_list) split into one new list of strings (new_list).
For example ['This is a Sentence', 'Also a sentence'] -> ['This', 'is', 'a', 'Sentence', 'Also', 'a', 'sentence'].
Steps:
Loop through the strings. for sentence in old_list:
Create a new string to keep track of the current word (word).
Loop through the characters in each of these strings. for ch in sentence:
If you come across the character(s) you want to split on (spaces in this example), check that word is not empty and add it to the new list, otherwise add the character to word.
Make sure to add word to the list after looping through all the characters.
The final code:
new_list = []
for sentence in old_list:
word = ''
for ch in sentence:
if ch == ' ' and word != '':
new_list.append(word)
word = ''
else:
word += ch
if word != '':
new_list.append(word)
This is equivalent to
new_list = []
for sentence in old_list:
new_list.extend(sentence.split(' '))
or even simpler
new_list = ' '.join(old_list).split(' ')
Case 2: One list of strings (old_list) split into a new list of lists of strings (new_list).
For example ['This is a Sentence', 'Also a sentence'] -> [['This', 'is', 'a', 'Sentence'], ['Also', 'a', 'sentence']].
Steps:
Loop through the strings. for sentence in old_list:
Create a new string to keep track of the current word (word) and a new list to keep track of the words in this string (sentence_list).
Loop through the characters in each of these strings. for ch in sentence:
If you come across the character(s) you want to split on (spaces in this example), check that word is not empty and add it to sentence_list, otherwise add the character to word.
Make sure to add word to sentence_list after looping through all the characters.
Append (not extend) sentence_list to the new list and move onto the next string.
The final code:
new_list = []
for sentence in old_list:
sentence_list = []
word = ''
for ch in sentence:
if ch == ' ' and word != '':
sentence_list.append(word)
word = ''
else:
word += ch
if word != '':
sentence_list.append(word)
new_list.append(sentence_list)
This is equivalent to
new_list = []
for sentence in old_list:
new_list.append(sentence.split(' '))
or using list comprehensions
new_list = [sentence.split(' ') for sentence in old_list]
This is simple code to split a char value from a string value; i.e
INPUT : UDDDUDUDU
s = [str(i) for i in input().strip()]
print(s)
OUTPUT: ['U','D','D','D','U','D','U','D','U']
sentence = 'This is a sentence'
word=""
for w in sentence :
if w.isalpha():
word=word+w
elif not w.isalpha():
print(word)
word=""
print(word)
string1 = 'bella ciao amigos'
split_list = []
tmp = ''
for s in string1:
if s == ' ':
split_list.append(tmp)
tmp = ''
else:
tmp += s
if tmp:
split_list.append(tmp)
print(split_list)
Output:
------> ['bella', 'ciao', 'amigos']
reverse_list = split_list[::-1]
print(reverse_list)
Output:
------> ['amigos', 'ciao', 'bella']
def mysplit(strng):
strng = strng.lstrip()
strng = strng.rstrip()
lst=[]
temp=''
for i in strng:
if i == ' ':
lst.append(temp)
temp = ''
else:
temp += i
if temp:
lst.append(temp)
return lst
print(mysplit("Hello World"))
print(mysplit(" "))
print(mysplit(" abc "))
print(mysplit(""))
This is one of the most accurate replicas of split method:
def splitter(x, y = ' '):
l = []
for i in range(x.count(y) + 1):
a = ''
for i in x:
if i == y: break
a += i
x = x[len(a) + 1 : len(x)]
l.append(a)
return ([i for i in l if i != ''])
my_str='This is a sentence'
split_value = []
tmp = ''
for i in my_str+' ':
if i == ' ':
split_value.append(tmp)
tmp = ''
else:
tmp += i
print(split_value)
Just a small modification to the code already given
I stuck on the following lab exercise:
The first piece we need is a routine that, given a word, will in
someway jumble up the order of all but the first and the last
characters. Rather than just randomly moving the characters around we
will reverse the order of the letters. The following code achieves
this:
def jumble(x):
return x[len(x)::-1]
my_string="Alistair"
print(" Reverse ",jumble(my_string))
Copy the above code to a file and run it. Currently it reverses the
order of all the characters in "my_string". Modify the code so that
the first and last letters of the word are NOT reversed. That is,
instead of producing "riatsilA" it produces "Aiatsilr".
This is my code for the above part:
def jumble(x):
temp0=x[0]
temp_last=x[-1]
x_new=temp0 + x[-2:0:-1] + temp_last
return x_new
my_string="Alistair"
print(" Reverse ",jumble(my_string))
The above routine does not account for leading or trailing white
space, punctuation or other characters that might legitimately be part
of the character string, but that should not be jumbled up. For
example if the string were " Alistair, " the result should be
" riatsilA, ". Modify your routine so that only the FIRST contiguous
series of alphabetical characters (minus the first and last
characters) are reversed. Ensure that the final returned string
includes all other leading and trailing characters.
I am not sure how to do this, as white space and punctuations can happen anywhere, I am thinking about have two lists, one for empty space and punctuations while another one for "contigous series of alphabetical characters", using append method to append elements to each list, but not sure how to preserve index.Can someone help me out? Thanks in advance.
#!/usr/bin/env python
#-*-coding:utf-8-*-
import re
def reverse(s):
p = re.compile(r'\w+')
for m in p.finditer(s):
word = m.group()
if word:
p = s.partition(word)
l = list(p)
index = p.index(word)
l[index] = l[index][::-1]
l2 = list(l[index])
l2[0],l2[-1]=l2[-1],l2[0]
l[index]=''.join(l2)
s = ''.join(l)
return s
s="Alistair Chris,"
print reverse(s)
fixed it.
The following code snipplet might help you for the last task.
There's no special handling for reverting of subsets, if a special char is found somewhere else than at start or end of the string.
# Special chars which should be ignored for reverting
SPECIALCHARS = [' ', '.', ',']
def reverse( string_ ):
# Find occurence of 'special' chars. Stack position and char into a list.
specchar = [( i, ltr ) for i, ltr in enumerate( string_ ) if ltr in SPECIALCHARS]
if specchar:
# Remove all the special characters
newstring = ''.join( c for c in string_ if c not in SPECIALCHARS )
# Reverse the legal characters
newstring = newstring[::-1]
offset = 0
# Re-insert the removed special chars
for pos, char in specchar:
if pos + 1 + offset >= len( newstring ):
# Append at the end
newstring += char
else:
# Insert
newstring = newstring[:pos + offset] + char + newstring[pos + offset:]
offset += 1
return newstring
else: # No special char at all, so just revert
return string_[::-1]
print " '%s' =?= ' riatsilA, '" % ( reverse( " Alistair, " ) )
will lead to the following output: ' riatsilA, ' =?= ' riatsilA, '
Just reverting with ignoring the first and last char is a one liner.
Using this one to invert the 'middle': t[1:-1][::-1]
Then add the first and last char to it.
>>> t = "Alistair"
>>> t[0]+t[1:-1][::-1]+t[-1]
'Aiatsilr'
Edit
Ok, now I think I understood what you want :-)
newstr = ""
fullstr = ""
for char in mystr:
if char in SPECIALCHARS:
if len( newstr ): # Is already something to invert there?
#Ignore 1st and last char and revert the rest
newstr = newstr[0] + newstr[1:-1][::-1] + newstr[-1]
fullstr += newstr + char
else: # Special char found but nothing to revert so far
fullstr += char
newstr = ""
else: # No special char so just append
newstr += char
print "'%s'" % fullstr
there is more elegant (pythonic + effective) way to find word on given position?
FIRST_WORD = re.compile(r'^(\w+)', re.UNICODE)
LAST_WORD = re.compile(r'(\w+)$', re.UNICODE)
def _get_word(self, text, position):
"""
Get word on given position
"""
assert position >= 0
assert position < len(text)
# get second part of word
# slice string and get first word
match = FIRST_WORD.search(text[position:])
assert match is not None
postfix = match.group(1)
# get first part of word, can be empty
# slice text and get last word
match2 = LAST_WORD.search(text[:position])
if match2 : prefix = match2.group(1)
else : prefix = ''
return prefix + postfix
# | 21.
>>> _get_word("Hello, my name is Earl.", 21)
Earl
>>> _get_word("Hello, my name is Earl.", 20)
Earl
Thanks
Here's how I'd do it:
s = "Hello, my name is Earl."
def get_word(text, position):
words = text.split()
characters = -1
for word in words:
characters += len(word)
if characters > = position:
return word
>>> get_word(s, 21)
Earl.
Stripping off the punctuation can be done with ''.strip() or regular expressions or something hacky like
for c in word:
final += c if c.lower() in 'abcdefghijklmnopqrstuvwxyz'
import string
s = "Hello, my name is Earl."
def get_word(text, position):
_, _, start = text[:position].rpartition(' ')
word,_,_ = text[position:].partition(' ')
return start+word
print get_word(s, 21).strip(string.punctuation)
The following solution is to get the alpha characters around the given position:
def get_word(text, position):
if position < 0 or position >= len(text):
return ''
str_list = []
i = position
while text[i].isalpha():
str_list.insert(0, text[i])
i -= 1
i = position + 1
while text[i].isalpha():
str_list.append(text[i])
i += 1
return ''.join(str_list)
The following is a test case:
get_word("Hello, my name is Earl.", 21) # 'Earl'
get_word("Hello, my name is Earl.", 20) # 'Earl'
I don't think it is a good idea to split the text into words with the split function here, because position is essential for this problem. If there are continuous blanks in a text, the split function may cause troubles.