replacing all integers in one list, with strings in another - python

testdeck = ['rock']
finaldeck = ['apple','banana','napalm','ice',5,6,7,8]
def deckhelp(testdeck,finaldeck):
testnumber = 0
testlength = len(testdeck)
for index, (card, item) in enumerate(zip(testdeck, finaldeck)):
if isinstance(item, int): #checks if item is an integer
finaldeck[index] = card
print(finaldeck)
testnumber += 1
if testnumber == testlength:
print('done')
pass
deckhelp(testdeck,finaldeck)
I want rock to replace the 5 located in finaldeck, can't seem to make it happen

This is not an appropriate use of zip() because you only want to iterate through testdeck when you reach the integers in finaldeck.
You also need to use return, not pass, to end the function when you reach the end of testdeck.
def deckhelp(testdeck, finaldeck):
testindex = 0
testlength = len(testdeck)
for index, item in enumerate(finaldeck):
if isinstance(item, int):
finaldeck[index] = testdeck[testindex]
testindex += 1
if testindex == testlength:
print('done')
return

Zip only works in testdeck and finaldeck have the same length. Instead, you can use something like this:
def deckhelp(testdeck, finaldeck):
replace_index = 0
for i, val in enumerate(finaldeck):
if isinstance(val, int):
finaldeck[i] = testdeck[replace_index]
replace_index += 1
if replace_index == len(testdeck):
print("done")
return

Related

RLE ALgorithm in python

like the title suggest I want to do an RLE algorithm and I have few problems with that
for example in RLE algorithm if we take aaaabbbccd it should return a4b3c2d1 as a result
the rle function should return the compressed string of aaabbbccccddddd
rle(data : str) : str
so it would be a3b3c4d5
Here's the code I know it's wrong but I don't know If it was a good way to begin
def rle(data):
data = 'aaabbbccccddddd'
for i in range(0,len(data)):
if data.count(f'{i}') > 1:
data.replace(i, data.count(f'{i}'))
print(data)
print(rle(data))
data = 'aaabbbccccddddd'
seq = []
r = None
for d in data:
if d != r:
seq.append(d)
seq.append(str(1))
r = d
else:
seq[-1] = str(int(seq[-1]) + 1)
print("".join(seq))
I thought that this code snippet is simple, and so didn't explain it...
we have a str and want to convert it to Char-TheNumberOfRepetitions pairs, like ['a',3,'b',3,'c',4,...], so we loop a char over str and when it is new, we add [char, 1] to list, otherwise, we add 1 to last element of list while we get a new char...
r variable is for new char recognition and is a temp variable that we store every new char (if a char was not equal to it, replace)
finally, we convert ['a',3,'b',3,'c',4,...] to str, using join
why we use str() and int()? because python join method is a bit silly :) and throw an exception, if an element of list be int... and everytime we convert it to int to add 1 and then convert to str, again...
why not map? because I assume that OP is beginner and map is complicate for him...
and, a more pythonic way:
def rle(data: str) -> str:
seq = [data[0], 1]
for elem in data[1:]:
if elem != seq[-2]:
seq += [elem, 1]
else:
seq[-1] += 1
return ''.join(map(str, seq))
and reverse:
def reverse_rle(data: str, end_char = '$') -> str:
def convert(): return seq[:-2] + [seq[-2] * (seq[-1] or 1)]
seq = [data[0], 0]
for elem in data[1:] + end_char:
if elem.isdigit():
seq[-1] = seq[-1] * 10 + int(elem)
else:
seq = convert()
if elem != end_char:
seq += [elem, 0]
return "".join(seq)
and if you dont want to use end_char:
def reverse_rle(data: str) -> str:
def convert(): return seq[:-2] + [seq[-2] * (seq[-1] or 1)]
seq = [data[0], 0]
for elem in data[1:]:
if elem.isdigit():
seq[-1] = seq[-1] * 10 + int(elem)
else:
seq = convert() + [elem, 0]
return "".join(convert())
This should work better
def rle(data):
# Initialize a few variables
prev = None
cnt = 0
res = ""
for i in data:
if i == prev:
# if same char as previous one, just add one to counter
cnt += 1
else:
# Check that we are not at first round and add to result
if prev != None:
res += "%s%s" % (cnt,prev)
# Set new character as previous one
prev = i
# Add last char to result
res += "%s%s" % (cnt,prev)
return res
print(rle("aaabbbccccddddd"))

list.remove(x) x seems to be in list but not being found

So in VSCode, I'm receiving this error...
Given the input
2
21 22
We have variables saying
best_choice = '22'
a: ['21', '22']
However, a.remove(best_choice) returns an error.
I am completely confounded... please help.
I checked for this problem on stacks and found that remove() doesn't work when iterating through a list, so I changed my loop to while(True). However, I'm still receiving the same error.
Here is the code:
import sys
def best_option(a):
iterator = 0
while(len(a)>1):
previous_best_digit = 0
current_best_digit = 0
best_short_option = []
return_list = []
for item in a:
if len(item)-1 < iterator:
char_previous = item[iterator-1:iterator]
dig_previous = ord(char_previous)
previous_best_digit = dig_previous
best_short_option = item
continue
char = item[iterator:iterator+1]
dig = ord(char)
if dig > current_best_digit:
current_best_digit = dig
return_list.clear()
return_list.append(item)
elif dig == current_best_digit:
return_list.append(item)
if (current_best_digit < previous_best_digit):
return_list.clear()
return_list.append(best_short_option)
a = return_list
iterator+=1
return a
def largest_number(a):
#write your code here
res = ""
while (True):
best_choice = best_option(a)
print(best_choice)
a.remove(best_choice)
res += best_choice
if (len(a)==1):
break
res.append(a)
print(res)
return res
if __name__ == '__main__':
input = sys.stdin.read()
data = input.split()
a = data[1:]
print(largest_number(a))
It's purpose create a string with the greatest possible value from a list of strings.
your best_choice is ['22'], not '22'

Entering floats into a list without overwriting list

I have some code here meant to allow me to keep creating floats until I input 0 to have it stop (the 0 is then deleted). These floats are supposed to be entered into a list. The issue I'm having is that each time the while loop is run, the float_list is overwritten.
again = True
float_count = 1
while (again):
float_list = [float(input("Float%d: " % i))for i in range(float_count, float_count + 1)]
last_float = float_list[-1]
if (last_float == 0):
again = False
del float_list[-1]
else:
float_count = float_count + 1
Is there any way to alter this code so all of the floats are entered into a list? Thanks!
This maybe a good option to use the alternative form of iter(fn, sentinel), e.g.:
float_list = [float(x) for x in iter(input, '0')]
If you need the prompt then you can create a helper function:
import itertools as it
fc = it.count(1)
float_list = [float(x) for x in iter(lambda: input('Float{}: '.format(next(fc))), '0')]
Or alternatively (most closely matches OP's attempt - would exit on 0, 0.0, 0.00, etc.):
fc = it.count(1)
float_list = list(iter(lambda: float(input('Float{}: '.format(next(fc)))), 0.0))
With error handling:
def get_float():
fc = it.count(1)
def _inner():
n = next(fc)
while True:
try:
return float(input("Float{}: ".format(n)))
except ValueError as e:
print(e)
return _inner
float_list = list(iter(get_float(), 0.0))
A list comprehension really isn't appropriate here. Much simpler:
float_count = 1
float_list = []
while True:
val = input("Float%d: " % float_count)
if val == '0':
break
float_list.append(float(val)) # call float(val) to convert from string to float
float_count += 1
it might be more user friendly to not crash if the user didn't type a float, e.g.:
def read_float(msg):
while 1:
val = input(msg)
if val == '0':
return val
try:
return float(val)
except ValueError:
print("%s is not a float, please try again.." % val)
def read_float_list():
float_count = 1
float_list = []
while True:
val = read_float("Float%d: " % float_count)
if val == '0':
break
float_list.append(val) # now val has been converted to float by read_float.
float_count += 1

Function based on conditions will not return value- python

I am new to this, and I am looking for help. I currently am stuck in a program I'm trying to complete. Here it is:
def searchStock(stockList, stockPrice, s):
for i in range(len(stockList)):
if s == stockList[i]:
s = stockPrice[i]
elif s != stockList[i]:
s = -1
return s
def mainFun():
stockList= []
stockPrice = []
l = 1
while l > 0:
stocks = str(input("Enter the name of the stock:"))
stockList += [stocks]
if stocks == "done"or stocks == 'done':
l = l * -1
stockList.remove("done")
else:
price = int(input("Enter the price of the stock:"))
stockPrice += [price]
l = l + 1
print(stockList)
print(stockPrice)
s = input("Enter the name of the stock you're looking for:")
s = searchStock(stockList, stockPrice, s)
Every time I run the program to the end, it never returns the variable s for some reason. If i replace return with print, it always prints -1 instead of the stockPrice if its on the list. I cant seem to get it to work. Can someone please help me?
Try adding this print to help you debug:
def searchStock(stockList, stockPrice, s):
output = -1
for i in range(len(stockList)):
if s == stockList[i]:
output = stockPrice[i]
print i, output, stockList[i], stockPrice[i]
elif s != stockList[i]:
output = -1
return output
Also I changed one of your variables, it seems better than modifying your input value and then returning it.

I need this Substring counting program to return a Tuple

I have come up with this piece of code to count multiple substrings within a string. I need for it to return the results in a tuple. Any Suggestions?
def FindSubstringMatch(target, key):
PositionList = 0
while PositionList < len(target):
PositionList = target.find(key, PositionList)
if PositionList == -1:
break
print(PositionList)
PositionList += 2
FindSubstringMatch("atgacatgcacaagtatgcat", "atgc")
This piece of code prints:
5
15
I would like for it to return:
(5,15)
Try this:
def FindSubstringMatch(target, key):
PositionList = 0
result = []
while PositionList < len(target):
PositionList = target.find(key, PositionList)
if PositionList == -1:
break
result.append(PositionList)
PositionList += 2
return tuple(result)
Even better, you can simplify the whole function like this:
from re import finditer
def findSubstringMatch(target, key):
return tuple(m.start() for m in finditer(key, target))
Either way, it works as expected:
findSubstringMatch("atgacatgcacaagtatgcat", "atgc")
=> (5, 15)

Categories

Resources