How can I loop through a string and print certain items? - python

lst = 'AB[CD]EF[GH]'
Output: ['A','B','CD','E','F','GH']
This is what I've tried but it's not working...
while(index < len(my_string)):
curr_char = my_string[index]
if(curr_char == '['):
while(curr_char != ']'):
multi = my_string[index + 1]
index += 1
lst += multi
Can anybody please help? Without importing Regex or whatever. I wanna do this without using it.

The problems with the original code seemed to be:
1) lst, index and multi are not initialised
2) the loop is infinite because the loop variable (index) isn't incremented on each iteration.
3) the close bracket needs to be skipped when detected to avoid including it in the final list
This code is an example of how to fix those issues:
def getList(s):
outList=[]
lIndex=0
while lIndex < len(s):
if s[lIndex] == "[":
letters=""
lIndex+=1
while s[lIndex] != "]":
letters+=s[lIndex]
lIndex+=1
outList.append(letters)
else:
outList.append(s[lIndex])
lIndex+=1
return outList
print(getList('AB[CD]EF[GH]'))

You can't use
lst += multi
because you can't concatenate a string with a list.
Moreover, your code enters an infinite loop, because you aren't updating the curr_char variable inside the inner loop, so the condition will always be True.
Also, you are not handling the case when curr_char != '['. And more errors there are.
You can use this code which fixes the above errors while using the same basic logic as your code:
index = 0
multi = ""
res = []
my_str = 'AB[CD]EF[GH]'
while (index < len(my_str)):
curr_char = my_str[index]
if curr_char == '[':
multi += curr_char
while curr_char != ']':
index += 1
curr_char = my_str[index]
multi += curr_char
res.append(multi)
multi = ""
else:
res.append(curr_char)
index += 1
print(res)
Output:
['A', 'B', '[CD]', 'E', 'F', '[GH]']

Please try the following code snippet.
my_string = 'AB[CD]EF[GH]'
lst = []
ind = 0
n = len(my_string)
while (ind < n):
if my_string[ind] == '[':
# if '[' is found, look for the next ']' but ind should not exceed n.
# Your code does not do a ind < n check. It may enter an infinite loop.
ind += 1 # this is done to skip the '[' in result list
temp = '' # create a temporary string to store chars inside '[]'
while ind < n and my_string[ind] != ']':
temp = temp + my_string[ind]
ind+=1
lst.append(temp) # add this temp string to list
ind += 1 # do this to skip the ending ']'.
else:
# If its not '[', simply append char to list.
lst.append(my_string[ind])
ind += 1
print(lst)

Related

Capital M is encountered, duplicate previous character (then remove the M), and capital N is encountered remove the next character from the string

Whenever a capital 'M' is encountered, duplicate the previous character (then remove the 'M')
Whenever a capital 'N' is encountered remove the next character from the string (then remove the 'N').
All other characters in the string will be lowercase letters.
For example: "abcNdgM" should return "abcgg". The final string will never be empty.
def StringChanges(str):
str2 = []
list = ""
for i in str:
if i == 'M':
str2.pop(i)
str -= 1
i -= 1
elif i == 'N':
if i == list - 1:
str2.pop()
else:
str2.append(i)
list -= 2
i -= 2
return ''.join(str2)
str = "oMoMkkNrrN"
print(StringChanges(str))
s ="MrtyNNNgjbM"
a = list(s)
if a[0] =="M":
a[0] = ""
for i in range(1,len(a)):
if a[i] == 'M':
if a[i-1] == '':
j = i-1
while a[j] == '':
j-=1
a[i] = a[j]
else:
a[i] = a[i-1]
if a[i] == "N":
c = 1
j = i+1
a[i] = ''
while a[j] == "N":
a[j] = ''
c+=1
j+=1
k = j
while c>0:
a[k] = ''
c-=1
k+=1
print(''.join(a))
Use re.sub like so:
import re
strings = ['abcNdgM', 'abcdg', 'MrtyNNgMM']
for s in strings:
# Repeat the cycles of transforming M/N with previous or subsequent characters:
while True:
s_new = re.sub(r'N.', '', re.sub(r'(.)M', r'\1\1', s))
if s == s_new:
break
s = s_new
# Remove any remaining Ms and Ns:
s = re.sub(r'[MN]+', '', s)
print(s)
# abcgg
# abcdg
# rtyggg
r'STRING': raw string.
. : any 1 character.
\1 : capture group 1, that is, whatever was matched by the pattern inside the parentheses.
In this python code, i is a string, taking on the value of each letter, one at a time, for each iteration through the for loop. But in the cupofprogramming example you linked, i is an integer representing the position (index) of a letter through each iteration of the loop. If you want this code to work with the index of each letter, take a look at how the enumerate() function works.

python function look and say sequence when parameter empty list

I need to define a function with a parameter list which generates the next line of the look and say sequence. My first code worked fine for generating the numbers.However, when calling the function with an empty list I need to get a result [1] and with this code I get an 'out of range' error.
The problem is that I define prev=line[0]. I tried many things and none works...My first idea was to try count,result=1,[1] and then define prev within a loop (for char in line: and then another one for char in line[1:]:)
This is my first code (generates correct number sequences but is out of it when function is called with an empty list):
def next_line(line):
prev,count, res = line[0], 1, []
for char in line[1:]:
if char != prev:
res += [count, prev]
count = 1
prev = char
elif char == prev:
count += 1
res.append(count)
res.append(prev)
return res
print(next_line([]))
Tried this but does not generate the correct number sequence!:
def next_line(line):
count,res = 1, [1]
for char in line:
prev=line[0]
if line[0]==1 and len(line)==1:
count=1
res=[1,1]
for char in line[1:len(line)+1]:
if char != prev:
res+=[count,prev]
count = 1
prev= char
else:
count += 1
return res
At best I get '1' in the beginning of my result and last elements missing...
I am new to python and really have no other ideas.
Thank you very much for your help!
Try the below code, Hope this will help :
Check for the length of the line before doing any processing on the list, as done in the below code.
def next_line(line):
if len(line) == 0:
return []
count,res = 1, [1]
for char in line:
prev=line[0]
if line[0]==1 and len(line)==1:
count=1
res=[1,1]
for char in line[1:len(line)+1]:
if char != prev:
res+=[count,prev]
count = 1
prev= char
else:
count += 1
return res
Ouput:
print(next_line([]))
[]
Same goes for your first solution:
def next_line(line):
if len(line) == 0:
return []
prev,count, res = line[0], 1, []
for char in line[1:]:
if char != prev:
res += [count, prev]
count = 1
prev = char
elif char == prev:
count += 1
res.append(count)
res.append(prev)
return res
print(next_line([]))
Ouput:
[]

Alternating letter in python

def myfunc(word):
result = ""
index = 0
for letter in word:
if index % 2 == 0:
result += letter.lower()
else:
result += letter.upper()
return result
index +=1
I am trying to return a matching string where every even letter is uppercase and every odd letter is lowercase. But the code doesn't show this exact result, any solution?
The problem is that you're only incrementing index after the loop, rather than each time through it. So, inside the loop, it's always 0. The smallest fix is:
def myfunc(word):
result = ""
index = 0
for letter in word:
if index % 2 == 0:
result += letter.lower()
else:
result += letter.upper()
index += 1
return result
But this kind of mistake is very easy to make (and sometimes not as easy as this to debug)—which is exactly why Python has nice tools like enumerate, that make it impossible to get wrong:
def myfunc(word):
result = ""
for index, letter in enumerate(word):
if index % 2 == 0:
result += letter.lower()
else:
result += letter.upper()
return result
People, including myself, have already pointed out your programming error. Here is an alternative one-liner solution to your problem using a generator expression and a ternary conditional operator:
def myfunc(word):
return "".join(w.upper() if i%2 else w.lower() for i,w in enumerate(word))
enumerate will return a tuple of the form (index, value) for each item in the iterable. In this case, the iterable is the string word.
At each step in the iteration, we check to see if the index i is odd.
i%2 will return 0 for even numbers and the if statement will evaluate to False.
Likewise, it will evaluate to True for odd numbers.
Respectively, we call lower() and upper() on the current character w.
Finally we use str.join to concatenate all the individual letters back together. Here we join the characters using an "" with is the empty string.
The problem was with how you were incrementing. You only set up your index to increment inside the "Else" block of your code. It was missing from the "If" block. As such as soon as you entered the "If" block you would be stuck there.
def myfunc(string):
result = ""
index = 0
for letter in string:
if index % 2 == 0:
result += letter.upper()
index += 1
else:
result += letter.lower()
index += 1
return result
def myfunc(word):
result = ""
for index, letter in enumerate(word):
if index % 2 == 0:
result += letter.lower()
else:
result += letter.upper()
return result
this worked for me.
Also it is much easier to understand the above block of code if you understand the enumerate function well
def myfunc(word):
index = 0
result = ''
for letter in word:
if index % 2 == 0:
result += letter.lower()
else:
result += letter.upper()
index += 1
print result
You weren't increment your index in the correct spot ;)
If you execute myfunc(word) it will print hElLo
def gonna(st) :
a = []
Index = 0
for index, c in enumerate(st) :
if index ℅ 2 == 0:
a.append(c.upper())
Index = Index + 1
else:
a.append(c.lower())
Index = Index + 1
return a
def myfunc(a):
result=""
for x in range(0,len(a)):
if x%2==0:
result=result+a[x].upper()
else:
result=result+a[x].lower()
return result
def myfunc(word):
z=list(word)
x=[]
y=[]
new_list=[]
str=""
for a in z:
x+=[a]
if len(x)==2:
y+=[x]
x=[]
for i in y:
odd=i[0].lower()
even=i[1].upper()
new_list.append(odd)
new_list.append(even)
for el in new_list:
str+=el
return str
def myfunc(str):
# Create an empty string to append the values to
result = ''
# Iterate through the loop using the enumerate function on the string so that you can use the index and the letter at the same time.
for index,letter in enumerate(str):
if index %2 == 0:
result += letter.lower()
else:
result += letter.upper()
# Return the string after all the letters have been appended to the string
return result
More Simpler , which is made using all the basic conecpts of Python
def myfunc(string):
new_string=""
for items in range(len(string)): # help us to to know about the index
if items % 2 == 0:
new_string = new_string + string[items].upper()
else:
new_string = new_string + string[items].lower()
return new_string
result=myfunc("Draco")
print(result)
def myfunc(word):
index=0
result = ''
for letter in word:
if index%2==0:
result=result+letter.upper()
else:
result=result+letter.lower()
index+=1
return result
**
Heading
**
def myfunc(word):
result = ""
for index, letter in enumerate(word):
if index % 2 == 0:
result += letter.upper()
else:
result += letter.lower()
return result

Count the consecutive letter in a string if the value 1 is there then it should be empty?

Suppose I am having the string "abbcccd" then it should show "ab2c3d"
Likewise I need to get the output?
My try. Very simple for with a temporary string as reference during the loop.
s = 'abbcccd'
new = ''
temp = ''
for i, letter in enumerate(s):
if i == 0:
temp += letter
continue
if letter == temp[-1]:
temp += letter
elif letter != temp[-1]:
new += temp[-1]
if len(temp) > 1:
new += str(len(temp))
temp = letter
new += temp[-1]
if len(temp) > 1:
new += str(len(temp))
as result you should get:
print (s)
>>>'ab2c3d'

index out of range even after initialization of var serving as index

I dont understand why this is out of range if I initialize j.
This expansion iterates all preceding characters of a slash, and when combined with a space, it is multiplied.
ie
5</ --> 5<5<
5<// --> 5<5<5<
5</ / --> 5<5< 5<5<
Also, is this the best way to accomplish my task?
def ttExpand( program ) :
"""
expand the string manipulation symbols in program into
a TinyTurtle language program.
program -- a TinyTurtle string, possibly with string manipulation symbols
Returns -- a TinyTurtle string after expansion
"""
new_program = ''
array = []
i = 0
j = 0
for ch in program: #while program.index(ch) != len(program) - 1:
if ch == '/':
array.append(program.index(ch))
i += 1
if len(array) == 0:
return program
while j <= len(array):
new_program += (program[:array[j]])
j += 1
return new_program
This doesn't produce the correct result, but it does do what you're trying to do:
#while j <= len(array):
for i in array:
new_program += program[:i] #(program[:array[j]])
It would appear that this approach actually accomplishes what you want:
def tt_expand(program):
'''
expand string manip symbols
Example:
>>> tt_expand('5</')
'5<5<'
>>> tt_expand('5<//')
'5<5<5<'
>>> tt_expand('5</ /')
'5<5< 5<5<'
'''
seen = ''
new_program = ''
prev_token = None
for i, token in enumerate(program):
if token == '/':
if prev_token == ' ':
new_program += new_program.rstrip()
else:
new_program += seen
else:
new_program += token
seen += token
prev_token = token
return new_program
if __name__ == '__main__':
import doctest
doctest.testmod()
The immediate cause is using while j <= len(array): then indexing array with j; sequences have indices starting at 0 and ending len(array) - 1 (usually described as being from 0 (inclusive) to len(array) (exclusive)).
The simple fix that preserves the majority of your code is to change to while j < len(array) so you stop at the last available index in array. That said, you're coding like you've just come from C, indexing instead of iterating.
If you ever find yourself with a loop that is structured like:
i = 0
while i < len(someseq):
item = someseq[i] # or equivalent, where you only use the value retrieved by indexing, not the index itself
what you really want is:
for item in someseq:
In rare cases, you might also need the index (when assigning back to the original sequence) in which case you'd do:
for i, item in enumerate(someseq):
Either of those is markedly faster and simpler than reinventing C-style for loops (rechecking the length on each pass and indexing adds a surprising amount of overhead compared to iterating directly).
You have to do:
while j <= len(array) - 1

Categories

Resources