list assignment index out of range in python - python

i am making a simple substitution cipher in python. i want this program to go through the characters in a string, then add their number values to an array, but it give me this error:
Traceback (most recent call last):
File "D:\py programs\simple cypher.py", line 39, in <module>
x[i]=18
IndexError: list assignment index out of range
here is my code:
pt=raw_input('string to encrypt ')
x=[]
for i in range (0, len(pt)):
if pt[i]=='a':
x[i]=1
elif pt[i]=='b':
x[i]=2
elif pt[i]=='c':
x[i]=3
elif pt[i]=='d':
x[i]=4
elif pt[i]=='e':
x[i]=5
elif pt[i]=='f':
x[i]=6
elif pt[i]=='g':
x[i]=7
elif pt[i]=='h':
x[i]=8
elif pt[i]=='i':
x[i]=9
elif pt[i]=='j':
x[i]=10
elif pt[i]=='k':
x[i]=11
elif pt[i]=='l':
x[i]=12
elif pt[i]=='m':
x[i]=13
elif pt[i]=='n':
x[i]=14
elif pt[i]=='o':
x[i]=15
elif pt[i]=='p':
x[i]=16
elif pt[i]=='q':
x[i]=17
elif pt[i]=='r':
x[i]=18
elif pt[i]=='s':
x[i]=19
elif pt[i]=='t':
x[i]=20
elif pt[i]=='u':
x[i]=21
elif pt[i]=='v':
x[i]=22
elif pt[i]=='w':
x[i]=23
elif pt[i]=='x':
x[i]=24
elif pt[i]=='y':
x[i]=25
elif pt[i]=='z':
x[i]=26
elif pt[i]==' ':
x[i]='_'
print x
can anybody help?

In Python you cannot assign to an index greater than the length of the list, so each of your x[i] = ... lines would cause this IndexError.
Instead you would need to change all of these to x.append(...), which will add a new element to the end of the list.
Really though, your entire code could be refactored so that it is much shorter:
import string
pt = raw_input('string to encrypt ')
trans = {c: i for i, c in enumerate(string.lowercase, 1)}
trans[' '] = '_'
x = [trans[c] for c in pt if c in trans]
print x

What you currently are trying to do is better written like this:
pt = raw_input('string to encrypt ')
x = [ord(i)-96 for i in pt]
If this really is what you need depends on what you intended to do next, but hopefully that takes you a bit further.

http://docs.python.org/2/library/string.html
string.maketrans(from, to)
Return a translation table suitable for passing to translate(), that will map each character in from into the character at the same position in to; from and to must have the same length.
Assign the translated to a separate list possibly? If this is what your looking for...
input_alphabet="abcde"
output_alphabet="12345"
trantab = maketrans(input_alphabet,output_alphabet)
text="translate abcdefg"
print text.translate(trantab)

Your list x is empty, so there is no x[i] to assign to: just as the error message says. Instead, use x.append(...). Or define x as x = [None] * len(pt) so that there are slots to fill.
Of course, there are much, much simpler and shorter ways of doing what you're trying to do. Try a dictionary, or the translate() method of strings.

The list is empty what you need is:
x.insert(i,1)
Which inserts the value 1 in index i

Related

Python extract variable in if statement and have checks

Is the below code valid in python or its not possible to extract variable in python and perform checks on it in one line?
def method1(self,some_text):
"""For illustration purpose it returns a hard coded value"""
return (1,2)
if x = method1("Hello") and x[0] == 1 and x[1] = 2:
print("This is it {},{}".format(x[0],x[1]))
elif x = method1("World") and x[0] == 3 and x[1] = 4:
print("This is it, second {},{}".format(x[0],x[1]))
elif x = method1("The") and x[0] == 5 and x[1] = 6:
print("This is it, third {},{}".format(x[0],x[1]))
else:
print("No match")
Currently I have this if condition for multiple attribute to check. Since python throws error because its not a valid syntax, I have to declare all such property above the if statement and so many attributes being declared in the local block.
Any better way or suggestion, to have extract the variable and have checks in one line as well as use the attribute within if block?
Check this:
def method1(some_text):
"""For illustration purpose it returns a hard coded value"""
return (1,2,3)
def printres(x):
for i in x:
res=method1(i[0])
if res[:2]==i[1]:
print(i[2].format(res[2]))
return
else:
print("No match")
printres([("Hello",(1,2),"This is it {}"),("World",(3,4),"This is it, second {}"),("The",(4,5),"This is it, third {}")])

Using a _linear_search helper method inside a linked list method

I am trying to remove all data = to the key given inside of a linked list.
v = 1
while v == 1:
p,c,i = self._linear_search(key)
if i == -1:
v += 1
if c is not None:
p._next = c._next
It removes the first value in the list but fails to continue and remove the following data = to the key in the linked list.
I am curious as to how this does not work, I am calling the helper method to find the key. Once a node is removed, why does it not call to the next node in the list to remove that one???
Thank you
Figured it out. Switching the
if i == -1:
v+=1
TO
elif i == -1:
v+=1
AT THE END OF THE LOOP:
However, Is someone able to use a computational approach to this, as to how the computer read my code.

I'm trying to replace a character in Python while iterating over a string and but it doesn't work

This is the code I currently have:
letter = raw_input("Replace letter?")
traversed = raw_input("Traverse in?")
replacewith = raw_input("Replace with?")
traverseint = 0
for i in traversed:
traverseint = traverseint + 1
if i == letter:
traversed[traverseint] = replacewith
print i
print(traversed)
str in python are immutable by nature. That means, you can not modify the existing object. For example:
>>> 'HEllo'[3] = 'o'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
In order to replace the character in the string, ideal way is to use str.replace() method. For example:
>>> 'HEllo'.replace('l', 'o')
'HEooo'
Without using str.replace(), you may make your program run by using a temporary string as:
my_str = '' # Temporary string
for i in traversed:
# traverseint = traverseint + 1 # Not required
if i == letter:
i = replacewith
my_str += i
Here my_str will hold the value of transformed traversed. OR, even better way to do this is by transforming the string to list (as mentioned by #chepner), update the values of list and finally join the list to get back the string. For example:
traversed_list = list(traversed)
for i, val in enumerate(traversed_list):
if val == letter:
traversed_list[i] = replacewith
print i
my_str = ''.join(traversed_list)
I can not comment yet, but want add a bit to Moinuddin Quadri answer.
If index of replacement is not required, str.replace() should be a best solution.
If replacement index is required, just use str.index() or str.find() for determine an replacement index, then use slice (see table) to "cut" ends and sum replacement between begin and end, or just call str.replace().
while True:
index = traversed.find(letter)
if index < 0:
break
print index
traversed = traversed[:index] + replacewith + traversed[index + len(letter):]
#or
traversed = traversed.replace(letter, replacewith, 1)
Str is immutable, so direct slice assignment is not possible.
If you want directly modify a string, you should use a mutable type, like bytearray.
To check if string contains a substring you can use in
letter in traversed
"System" does not allow me to post more than 2 links. But all methods I have mentioned are on the same page.
You shouldn't modify containers you are iterating over. And you cant edit strings by position.
Make a copy of the string first and make it a list object
letter = raw_input("Replace letter?")
traversed = raw_input("Traverse in?")
modify = list(traversed)
replacewith = raw_input("Replace with?")
for traverseint,i in enumerate(modify):
if i == letter:
modify[traverseint] = replacewith
print i
print(''.join(modify))
You can also just create empty string and add letters (python 3.5)
letter = input("Replace letter?")
traversed = input("Traverse in?")
replacewith = input("Replace with?")
temp = ''
for i in traversed:
if i == letter:
temp += replacewith
else:
temp += i
print(temp)
We can also define own replace like below:
def replace(str, idx, char):
if -1 < idx < len(str):
return '{str_before_idx}{char}{str_after_idx}'.format(
str_before_idx=str[0:idx],
char=char,
str_after_idx=str[idx+1:len(str)]
)
else:
raise IndexError
Where str is string to be manipulated, idx is an index, char is character to be replaced at index idx.

Getting the middle character in a odd length string

def get_middle_character(odd_string):
variable = len(odd_string)
x = str((variable/2))
middle_character = odd_string.find(x)
middle_character2 = odd_string[middle_character]
return middle_character2
def main():
print('Enter a odd length string: ')
odd_string = input()
print('The middle character is', get_middle_character(odd_string))
main()
I need to figure out how to print the middle character in a given odd length string. But when I run this code, I only get the last character. What is the problem?
You need to think more carefully about what your code is actually doing. Let's do this with an example:
def get_middle_character(odd_string):
Let's say that we call get_middle_character('hello'), so odd_string is 'hello':
variable = len(odd_string) # variable = 5
Everything is OK so far.
x = str((variable/2)) # x = '2'
This is the first thing that is obviously odd - why do you want the string '2'? That's the index of the middle character, don't you just want an integer? Also you only need one pair of parentheses there, the other set is redundant.
middle_character = odd_string.find(x) # middle_character = -1
Obviously you can't str.find the substring '2' in odd_string, because it was never there. str.find returns -1 if it cannot find the substring; you should use str.index instead, which gives you a nice clear ValueError when it can't find the substring.
Note that even if you were searching for the middle character, rather than the stringified index of the middle character, you would get into trouble as str.find gives the first index at which the substring appears, which may not be the one you're after (consider 'lolly'.find('l')...).
middle_character2 = odd_string[middle_character] # middle_character2 = 'o'
As Python allows negative indexing from the end of a sequence, -1 is the index of the last character.
return middle_character2 # return 'o'
You could actually have simplified to return odd_string[middle_character], and removed the superfluous assignment; you'd have still had the wrong answer, but from neater code (and without middle_character2, which is a terrible name).
Hopefully you can now see where you went wrong, and it's trivially obvious what you should do to fix it. Next time use e.g. Python Tutor to debug your code before asking a question here.
You need to simply access character based on index of string and string slicing. For example:
>>> s = '1234567'
>>> middle_index = len(s)/2
>>> first_half, middle, second_half = s[:middle_index], s[middle_index], s[middle_index+1:]
>>> first_half, middle, second_half
('123', '4', '567')
Explanation:
str[:n]: returns string from 0th index to n-1th index
str[n]: returns value at nth index
str[n:]: returns value from nth index till end of list
Should be like below:
def get_middle_character(odd_string):
variable = len(odd_string)/2
middle_character = odd_string[variable +1]
return middle_character
i know its too late but i post my solution
I hope it will be useful ;)
def get_middle_char(string):
if len(string) % 2 == 0:
return None
elif len(string) <= 1:
return None
str_len = int(len(string)/2))
return string[strlen]
reversedString = ''
print('What is your name')
str = input()
idx = len(str)
print(idx)
str_to_iterate = str
for char in str_to_iterate[::-1]:
print(char)
evenodd = len(str) % 2
if evenodd == 0:
print('even')
else:
print('odd')
l = str
if len(l) % 2 == 0:
x = len(l) // 2
y = len(l) // 2 - 1
print(l[x], l[y])
else:
n = len(l) // 2
print(l[n])

An error in python

im new..
my script is pretty long so I'll write down the specific parts.
str= ''
#str is a long DNA sequence
def FIND_UPPER(str):
global x
x=str.upper()
y=0
while y>(-1):
y=x.find('CTTTGATTCCT')
z=x[y+11:y+22]
x=x[y+23:]
variability(z)
#variability is another function
FIND_UPPER(str)
and then I get this message:
list indices must be integers, not str
about those lines:
variability(z)
FIND UPPER(str)
How can I fix this?
thanks
edit:
this is variability:
A=[0]*10
C=[0]*10
T=[0]*10
G=[0]*10
def variability(z):
for i in z:
if i=='A':
A[i]=A[i]+1
i=i+1
elif i=='T':
T[i]=T[i]+1
i=i+1
elif i=='C':
C[i]=C[i]+1
i=i+1
elif i=='G':
G[i]=G[i]+1
i=i+1
return G
return C
return T
return A
I fixed it, can u tell me if I got u right?
:
def variability(z):
for i in range(len(z)):
if i=='A':
A[i]=z[i]
A[i]+=1
i+=1
elif i=='T':
T[i]=z[i]
T[i]+=1
i+=1
elif i=='C':
C[i]=z[i]
C[i]+=1
i+=1
elif i=='G':
G[i]=z[i]
G[i]+=1
i+=1
return G,C,T,A
def variability(z):
for i in z:
if i=='A':
A[i]=A[i]+1
i=i+1
Assume i == 'A', then A[i] is actually translated to A['A'] which returns:
list indices must be integers, not str
Which means you can't access a list by a string index, list indices are integers.
Moreover, Python doesn't support multiple return statements:
return G
return C
return T
return A
This will always return G
If you want to return all of these values, then replace it with:
return G,C,T,A
The above return statements returns a tuple consists G,C,T,A
If you want to return just one, place each return statement inside your elif clauses.
In the loop you have to do something like:
for i in range(len(z)):
letter = A[i]
If you iterate over range function result, "i" will take numeric values. If you iterate over the string i will take each character of the string
An then compare variable "letter"
if letter == 'A':
...
Be careful in the variability function, only the value in the first return statement will be returned.

Categories