I am currently trying to create a code that can scan a string, put the position of each letter found in a list associated to the letter (ex : if you find a S as the 35, 48 and 120 letter of the string, it will put 35, 48, and 120 in a list for the letter S). It will then put this list in a dictionary as a value with S for key.
My problem is simple, I have an IndexError: list assignment index out of range when I try to put the value in the list, but I cant find out why.
string = "Squalalanoussommespartisetjetedteste"
taille = len(string)
dico = dict()
dico = {}
i = 0
for i in range(taille):
if string[i] == "A" or string[i] == "a" :
va = 0
valA = []
valA[va] = i
va = va + 1
print(valA)
I apologize for my poor English, and thank by advance for the help.
You don't need to specify an index while pushing an item to a list in python. Try this:
for i in range(taille):
if string[i] == "A" or string[i] == "a" :
valA = []
valA.append(i)
print(valA)
You are getting this error in these lines
va = 0
valA = []
valA[va] = i
valA is blank list here, with zero elements, so when you try to assign a value to its 0 index, it raises IndexError.
Also to get indexes for each character you can directly loop over string, like
s = "Squalalanoussommespartisetjetedteste"
d = dict()
for i, c in enumerate(s):
d.setdefault(c.lower(), []).append(i)
print d
I found some errors in the code.
The index error is because you tried to call 0th position of an empty list.
valA = []
The list is empty. Then you tried to replace value at the 0th position when there is no 0th position
valA[va] = i
I made some changes to the code. In the ninth line you initialize an empty list. You should do that before for loop. Otherwise for loop initiate it everytime and you lose the value in the previous loop.
here is the modified code.
string = "Squalalanoussommespartisetjetedteste"
taille = len(string)
dico = dict()
dico = {}
i = 0
valA = []
for i in range(taille):
if string[i] == "A" or string[i] == "a":
valA.append(i)
print(valA)
The output i got is
[3, 5, 7, 19]
Though you may use straightforward approach, Python has some usefull modules that may help. For example
import collections
s = "Squalalanoussommespartisetjetedteste"
result = collections.defaultdict(list)
for i,char in enumerate(s):
result[char].append(i)
result would contain a dictionary with string characters as keys and lists if char's indexes as items.
You are redefining variables below everytime. So move them to out of loop.
va = 0
valA = []
Also use insert method for list. (You can use insert for when you need to use define index in list. otherwise append is enough)
so final code :
string = "Squalalanoussommespartisetjetedteste"
taille = len(string)
dico = dict()
dico = {}
i = 0
va = 0
valA = []
for i in range(taille):
if string[i] == "A" or string[i] == "a" :
valA.insert(va, i)
va = va + 1
print(valA)
index error, because array valA is empty array, that means there are no indexes...
use function append and declare array valA outside the loop...
string = "Squalalanoussommespartisetjetedteste"
taille = len(string)
dico = dict()
dico = {}
i = 0
valA = []
for i in range(taille):
if string[i] == "A" or string[i] == "a" :
valA.append(i)
print(valA)
Related
I am trying to find greatest length of a word from the string return it by using values of each letter from alphabets by assigning each letter it's value as per it's rank . So for example For a string s = 'abcd a', I intend to return 10 [a=1 + b=2 + c =3 + d=4] .But, I am getting output as 7 When I debugged the code, I noticed that in while loop my code skips i=2 and directly jumps on i=3. Where am I going wrong? Below is my code.
class Solution(object):
def highest_scoring_word(self,s):
# Dictionary of English letters
dt = {'a':1,'b':2,'c':3,'d':4,'e':5,'f':6,
'g':7,'h':8,'i':9,'j':10,'k':11,'l':12,
'm':13,'n':14,'o':15,'p':16,'q':17,
'r':18,'s':19,'t':20,'u':21,'v':22,
'w':23,'x':24,'y':25,'z':26}
value_sum =0
max_value =value_sum
for i in range(0,len(s)):
if s.upper():
s= s.lower()
words = s.split()
# convert the string in char array
to_char_array = list(words[i])
j=0
while j<len(to_char_array):
if to_char_array[j] in dt.keys() :
value_sum = max(dt.get(to_char_array[j]),value_sum + dt.get(to_char_array[j]))
max_value = max(value_sum,max_value)
else:
pass
j +=j+1
return max_value
if __name__ == '__main__':
p = 'abcd a'
print(Solution().highest_scoring_word(p))
`
I have created a dictionary where I have stored all letters in english alphabet and their values and later I have split the string into words using split() and then after converting each individual word into character array I have traversed it to find their occurrence in the dictionary and add to the final value. I am expecting to get a correct value of a string and finally the greatest value.
As you are using a class and methods, make use of them:
from string import ascii_lowercase as dt
class Solution(object):
def __init__(self, data):
self.scores = {}
self.words = data.lower().strip().split()
def get_scoring(self):
# for each word caculate the scoring
for word in self.words:
score = 0
# for each character in the word, find its index in 'a..z' and add it to score
# same as in your dt implementation (just using index not absolute values)
for c in word:
score += dt.find(c) + 1
self.scores[word] = score
print(self.scores)
# filer the dictionary by its greates value in order to get the word with max score:
return max(self.scores.keys(), key=lambda k: self.scores[k])
if __name__ == '__main__':
p = 'abcd fg11'
maxWord = Solution(p).get_scoring()
print(maxWord)
Out:
{'abcd': 10, 'fg11': 13}
fg11
Try using this:
class Solution(object):
def highest_scoring_word(self,s):
# Dictionary of English letters
dt = {'a':1,'b':2,'c':3,'d':4,'e':5,'f':6,
'g':7,'h':8,'i':9,'j':10,'k':11,'l':12,
'm':13,'n':14,'o':15,'p':16,'q':17,
'r':18,'s':19,'t':20,'u':21,'v':22,
'w':23,'x':24,'y':25,'z':26}
value_sum1 =0
max_value1 =value_sum1
value_sum2 =0
max_value2 =value_sum2
for i in range(0,len(s)):
if s.upper():
s= s.lower()
words = s.split()
if len(words)>1:
# convert the string in char array
to_char_array = list(words[0])
j=0
while j<len(to_char_array):
if to_char_array[j] in dt.keys() :
value_sum1 = max(dt.get(to_char_array[j]),value_sum1 + dt.get(to_char_array[j]))
max_value1 = max(value_sum1,max_value1)
else:
pass
j=j+1
to_char_array = list(words[1])
j=0
while j<len(to_char_array):
if to_char_array[j] in dt.keys() :
value_sum2 = max(dt.get(to_char_array[j]),value_sum2 + dt.get(to_char_array[j]))
max_value2 = max(value_sum2,max_value2)
else:
pass
j=j+1
if max_value2>max_value1:
return max_value2
elif max_value1>max_value2:
return max_value1
else:
return 'Both words have equal score'
else:
# convert the string in char array
to_char_array = list(words[i])
j=0
while j<len(to_char_array):
if to_char_array[j] in dt.keys() :
value_sum1 = max(dt.get(to_char_array[j]),value_sum1 + dt.get(to_char_array[j]))
max_value1 = max(value_sum1,max_value1)
else:
pass
j=j+1
return max_value1
if __name__ == '__main__':
p = 'abcd fg'
print(Solution().highest_scoring_word(p))
It is maybe of interest that the code can be greatly simplified by using features available in Python:
the_sum = sum(ord(c)-96 for c in s.lower() if c.isalpha())
to break this down. for c in s.lower() gets the lower-case characters one by one; the function ord() gives the numerical value with a of 97 so we subtract to get 1. Then we check if the character is a letter and if so accept it. Then sum() adds up all the numbers. You could break up this one line an check how the separate parts work.
I have this text:
>A1
KKKKKKKK
DDDDDDDD
>A2
FFFFFFFF
FFFFOOOO
DAA
>A3
OOOZDDD
KKAZAAA
A
When I split it and remove the line jumps, I get this list:
It gives me a list that looks like this:
['>A1', 'KKKKKKKK', 'DDDDDDDD', '>A2', 'FFFFFFFF', 'FFFFOOOO', 'DAA', '>A3', 'OOOZDDD', 'KKAZAAA', 'A']
I'm trying to merge all the strings between each part that starts with '>', such that it looks like:
['KKKKKKKKDDDDDDDD', 'FFFFFFFFFFFFOOOODAA', 'OOOZDDDKKAZAAAA']
What I have so far, but it doesn't do anything and I'm lost:
my_list = ['>A1', 'KKKKKKKK', 'DDDDDDDD', '>A2', 'FFFFFFFF', 'FFFFOOOO', 'DAA', '>A3', 'OOOZDDD', 'KKAZAAA', 'A']
result = []
for item in range(len(my_list)):
if my_list[item][0] == '>':
temp = ''
while my_list[item] != '>':
temp += my_list[item]
result.append(temp)
print(result)
#Andrej has given a compact code for your problem, but I want to help you by pointing out some issues in your original code.
You have while in if, but when my_list[item] starts with '>', the inner while won't work. The correct thing is to add a else-statement to concatenate the following string.
You append a string temp to result at each iterative step, but temp is not a concatenated string. The correct time to append is when you meet '>' again.
After solving them, you may get something like this,
result = []
for item in range(len(my_list)):
if my_list[item][0] == '>':
if item != 0:
result.append(temp)
temp = ''
else:
temp += my_list[item]
if item != 0:
result.append(item)
print(result)
You can further simplify it.
Save list indexing by directly iterating over the list.
Save final repeated check by adding a sentinel.
result = []
concat_string = '' # just change a readable name
for string in my_list + ['>']: # iterate over list directly and add a sentinel
if string[0] == '>': # or string.startswith('>')
if concat_string:
result.append(concat_string)
concat_string = ''
else:
concat_string += string
print(result)
You can use itertools.groupby for the task:
from itertools import groupby
lst = [
">A1",
"KKKKKKKK",
"DDDDDDDD",
">A2",
"FFFFFFFF",
"FFFFOOOO",
"DAA",
">A3",
"OOOZDDD",
"KKAZAAA",
"A",
]
out = []
for k, g in groupby(lst, lambda s: s.startswith(">")):
if not k:
out.append("".join(g))
print(out)
Prints:
["KKKKKKKKDDDDDDDD", "FFFFFFFFFFFFOOOODAA", "OOOZDDDKKAZAAAA"]
Regex version:
data = """>A1
KKKKKKKK
DDDDDDDD
>A2
FFFFFFFF
FFFFOOOO
DAA
>A3
OOOZDDD
KKAZAAA
A"""
import re
patre = re.compile("^>.+\n",re.MULTILINE)
#split on `>xxx`
chunks = patre.split(data)
#remove whitespaces and newlines
blocks = [v.replace("\n","").strip() for v in chunks]
#get rid of leading trailing empty blocks
blocks = [v for v in blocks if v]
print(blocks)
output:
['KKKKKKKKDDDDDDDD', 'FFFFFFFFFFFFOOOODAA', 'OOOZDDDKKAZAAAA']
Given the following list:
list = [2,10,10,10,4,5]
How can I write a function that returns the output:
output = 210AA:45
I was working with this code so far, but don't know what else to add so that once a number between 10 and 15 is repeated, return the repeated number in its hexadecimal form as in the output
def int_to_string(data):
string = ""
for i in data:
hexadecimal = hex(i)
string += hexadecimal[2:]
string[0] = 15
return string
Use a list [] instead of a string ""
strings are immutable and don't support index lookup and assignment.
append the hex val and then edit the first index as you see fit to get your result
and retun a joined list with
''.join(#ur_lst)
A dictionary describing the mapping between decimal and hex could add readability.
Remark: don't shadow the name of build-functions, in this case list. See doc for a complete list.
lst = [2,10,10,10,4,5,13,15,0] # <- new testing list
# dictionary for conversion
num2hex = {i: str(i) for i in range(10)}
num2hex.update(zip(range(10, 16), "ABCDEF"))
# conversion list -> str
res = ''
consecutve_hex, is_last_hex = 0, False
for d in lst:
if 10 <= d <= 15:
consecutive_hex += 1
is_last_hex = False
if consecutive_hex > 1:
res += num2hex[d]
else:
res += str(d)
else:
if not is_last_hex:
if res:
res += ':'
consecutive_hex = 0
is_last_hex = True
res += str(d)
print(res)
#210AA:4513F:0
I'm trying to create this code so that when variable J is present, it is a positive number, but if H is present, it is a negative number. Here is my code.
record = ['1J2H']
def robot_location(record: str):
if J in record:
sum()
if H in record:
** I dont know how to subtract them**
print(robot_location(record)
So if record = [1J2H] then the output should be ((+1)+(-2)) = -1 should be the output... how can I do that?? Somebody pls help explain this.
You need to iterate over string inside list, check char by char and asume thats always length of string will be odd
record = ['1J2H']
def robot_location(record: str):
total = 0
aux_n = 0
for a in record:
if a.isnumeric():
aux_n = int(a)
else:
if a == 'H':
total = total + aux_n*-1
else:
total = total + aux_n
aux_n = 0
return total
print(robot_location(record[0]))
Here is a concise way to do this via a list comprehension:
record = '1J2H'
nums = re.findall(r'\d+[JH]', record) # ['1J', '2H']
output = sum([int(x[:-1]) if x[-1] == 'J' else -1*int(x[:-1]) for x in nums])
print(output) # -1
One way to do that is by using iter and converting the string into an iterable, that allows to use next which moves the iteration to the next item meaning that if one simply iterates over it it will get moved to the next item and then if one uses next it will return the current value where the "pointer"? is and move it to the next value so the next iteration with a for loop (list comprehension in this case) will get the next value, meaning that the loop will return only the numbers while next will return only the letters:
lst = ['1J2H']
def robot_location(record: str):
record = iter(record)
numbers = [int(i) if next(record) == 'J' else -int(i) for i in record]
return sum(numbers)
print(robot_location(lst[0]))
You could modify a string like s = '1J2H' to '1+2*-1+0' and let Python evaluate it:
result = eval(s.replace('J', '+').replace('H', '*-1+') + '0')
a = ["0$%","0%%%","0$%$%","0$$"]
The above is a corrupted communication code where the first element of each sequence has been disguised as 0. I want to recover the original and correct code by computing a list of all possible sequences by replacing 0 with either $ or % and then checking which of the sequences is valid. Think of each sequence as corresponding to an alphabet if correct. For instance, "$$$" could correspond to the alphabet "B".
This is what I've done so far
raw_decoded = []
word = []
for i in a:
for j in i:
if j == "0":
x = list(itertools.product(["$", "%"], *i[1:]))
y = ("".join(i) for i in x)
for i in y:
raw_decoded.append(i)
for i in raw_decoded:
letter = code_dict[i] #access dictionary for converting to alphabet
word.append(letter)
return word
Try that:
output = []
for elem in a:
replaced_dollar = elem.replace('0', '$', 1)
replaced_percent = elem.replace('0', '%', 1)
# check replaced_dollar and replaced_percent
# and then write to output
output.append(replaced_...)
Not sure what you mean, perhaps you could add a desired output. What I got from your question could be solved in the following way:
b = []
for el in a:
if el[0] == '0':
b.append(el.replace('0', '%', 1))
b.append(el.replace('0', '$', 1))
else:
b.append(el)