Manipulating list based on the first and second index integer - python

I need help fixing this code. My goal is to change the last element of the indexed string from "3" to "F" if the two indexes before are an even integer.
change = ['E013', 'E023', 'E033', 'E042', 'E054']
def help():
for i in change:
test = int(i[1:3])
if test % 2 == 0 and i[3] == "3":
subs = [i.replace("3","F") for i in change]
print(subs)
help()
So for example if you have a list:
INPUT
change = ['E013', 'E023', 'E033', 'E042', 'E054']
I want this to output:
OUTPUT
change = ['E013', 'E02F', 'E033', 'E042', 'E054']
Right now my code is outputting:
['E01F', 'E02F', 'E0FF', 'E042', 'E054']

You have to change just one of the elements in the list, not all of them:
change = ["E013", "E023", "E033", "E042", "E054"]
for index, value in enumerate(change):
test = int(value[1:3])
print(f"doing {index} {value} {test}")
if test % 2 == 0 and value[3] == "3":
print(f"changing index {index}")
# strings are immutable in python, and .replace creates a new one
# which has to be assigned in the list
change[index] = value.replace("3", "F")
print(change)
Note that I left the test value[3] == "3" that you had, so E042 is not modified, as it does not end with 3. If you only need to check if the number is even, remove that.
Cheers!

Related

Python replacing one list with another

I have one list like this list = [] and in this list there are elements like this
15,a,90 -
16,c,60 -
17,e,50 -
The output of the list[0] is 15,16,17 and i have code like this
ogrno = input("a")
for i in ogr.list:
if ogrno == i[0]:
add = [input("new number "),input("new word"),input("new number")
i = add
I want to add a new list instead of the selected line here.But "i" not used.
This fails for the same reason that a = 3; i = a; i = 2 doesn't change the value of a: assigning to a name never affects the object currently bound to that name. If you want to change what a list references, you need to assign to the list slot itself.
for i, value in enumerate(ogr.list):
if ogrno == value[0]:
ogr.list[i] = [input("new number "),input("new word"),input("new number")]

How to delete an item from a list by python only using recursion

How do I write a code in python by only using the recursion without loops and any build in methods or functions? I tried:
def myRemove(x, cont): # x is a string inside of the list cont
if x == cont:
return None
elif len(x) > len(cont):
return None
else:
if "x" not in cont[0]:
return myRemove(x,cont[1:])
else:
return cont
Some problems I see in your code:
1. Difference between a string and a variable
You have the following line in your code which is semantically wrong:
if "x" not in cont[0]:
...
Here "x" is the string 'x' and not the value of x. To fix this remove the quotation marks.
if x not in cont[0]:
...
2. Difference between list and variable
To check if a variable is in a list use in. e.g.
>>> "test" in ["test", "wow", "u"]
true
To check if a variable is equal to another variable use ==. e.g.
>>> "test" == ["test", "wow", "u"][0]
true
The fixed part of your code: (Because cont[0] returns a value and not a list)
if x == cont[0]:
...
3. Returns in recursion
You have to concatenate the returned list with the list part before the other list.
Otherwise, you are always returning the last part of the list.
One possible solution
def remove(string, string_list):
if string_list[0] == string:
return string_list[1:]
else:
return string_list[:1] + remove(string,string_list[1:])
def recursive_remove(x: str, cont: list):
""" removes items equal to x using recursion only
cont: list of strings
x: string to remove from list
"""
if len(cont) == 0:
return []
if cont[0] != x:
return [cont[0]] + recursive_remove(x=x, cont=cont[1:])
else:
return recursive_remove(x=x, cont=cont[1:])
list_without_banana = recursive_remove(x='banana', cont=['apple', 'banana', 'strawberry', 'peanut'])
print(list_without_banana)
>>>['apple', 'strawberry', 'peanut']

How to print only when something gets added into a list?

I got an idea where you have a list etc. of [1,2,3,4,5] and my idea was that incase a number of those gets pop/deleted then it shouldn't print. Let's say etc. we remove number 3. In that case our list would be [1,2,4,5] and the script should be usual. But whenever a value gets added to a list. Then print out the whole list so etc. add number 6 – > [1,2,4,5,6] - Print out the whole list.
The problem is that I don't want to get notified whenever there has been anything deleted so my idea from the beginning was to check the length of a list and then notify whenever it gets changed but then I realized that the wrong I am doing is that it going to notify whenever it gets added and/nor deleted which now why I am here.
What I did was a compare of a new_name_list vs old_name_list but this one is going to notify for whatever change that would be happens basically.
import names
def get_value(value):
value = names.get_full_name()
names_list = []
for names in names.get_last_name():
names_list.append(names)
break
identifier = ('{} {}').format(value, names_list)
return identifier
if __name__ == '__main__':
old_name_list = get_value()
while True:
new_name_list = get_value()
if new_name_list not in old_name_list:
print("Yay new name added")
else:
print('I will re try again in 5 sec')
time.sleep(5)
My question is - How can I make it so it print only whenever the value of names_list will get notified ONLY when something gets added but not deleted?
etc.
1. [1,2,3,4,5] - print from beginning
2. [1,2,4,5] - Deleted 3 - Do not print
3. [1,2,4,5,6] - Print list, something got added
4. [1,4,5,6] - Deleted 2 - Do not print
5. .........
Algorithm could be the following:
Order old and new lists.
If length is equal -> compare element-to-element. If new list contains different elements than old list, means new values were added.
If new list length > old list length, also means, that new elements were added.
Example:
def detect_change(old_list, new_list):
changed_flag = False
old_list.sort()
new_list.sort()
if len(old_list) == len(new_list):
for i in range(0, len(old_list)):
if old_list[i] != new_list[i]:
changed_flag = True
elif len(old_list) < len(new_list):
changed_flag = True
return changed_flag
list1 = ["a", "b", "c", "d"]
list2 = ["a", "b", "c", "k"]
print(detect_change(list1, list2))

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])

How to get the last occurrence of list as output?

Can anyone please explain how to output the rightmost index from several most-same-values indexes in the list?
my function:
def last_index(xs,key):
i = 0
for i in range(len(xs)):
if xs[i] == key:
if i != len(xs):
return i
else:
return 'None'
for example,
xs = [3,4,5,6,4,4,5]
key = 4
the rightmost index output should be a single 5. But I got all three all them which are index 1,4,5.
Thanks for the help, and sorry I'm totally new.
what if the input as strings like:
xs=[True,True,True,False]
key = True
I believe the output is 2?
This simple solution should do:
def last_index(xs, key):
index = None
for i in xrange(len(xs)):
if xs[i] == key:
index = i # override index, result in the rightmost index of key
return index # returns None if key is not on the list
A more efficient way to do this is by iterating from the end to start and returning the index when key is found, in worst case - key is not found and we will iterate over the entire list.
Check out the more efficient version:
def last_index(xs, key):
index = None
for i in xrange(len(xs)-1, 0, -1): # iterate from last item to first
if xs[i] == key:
index = i
break # found the rightmost index, exit the loop
return index
Notice you should prefer using xrange over range (unless in python 3 where range equals to xrange), also to avoid an edge case when items involve different types see Andriy's answer.
You can try a function like this
def last_index(xs,key):
index = -1
for i in range(len(xs)):
if xs[i] == key:
index=i
if index!=-1:
return index
else:
return "none"
This will get the last index that matches your key. If there is none will return "none".
This should do the trick:
def last_index(xs,key):
index = -1
for i in range(len(xs)):
if xs[i] != key:
continue
else:
index = i
return index if index != -1 else 'None'
Traverse xs in reverse order and return first matched value, with reversed function:
def last_index(xs,key):
for i in reversed(range(len(xs))):
if xs[i] == key:
return i
xs = [3,4,5,6,4,4,5]
key = 4
print last_index(xs, key) # output: 5
xs=[True,True,True,False]
key = True
print last_index(xs, key) # output: 2
print last_index(xs, 2) # output: None
NOTE#1
You can use xrange instead of range it would give you better performace and won't be deprecated since python3, see Should you always favor xrange() over range()? for more info.
Your comparison may be improved by replacing
if xs[i] == key
to
if xs[i] == key and type(a) == type(b)
NOTE#2
To avoid bug when your 1 == True would return you index of True however you wanna index of 1 whicn not exist, compare result for both if conditions when xs and key have values below
xs=[True,True,True,False]
key = 1
See Strict comparison for more information about that behaviour.
You can reverse the list and then use .index():
index = xs[len(xs) - list(reversed(xs)).index(key)]
By the way, in your second list, True and False are booleans, not strings.
Iterate from behind like this:
def last_index(xs,key):
i= len(xs)-1
while i >=0:
if xs[i] == key:
return i
i -= 1
This way if the key does not exist the function will return the none value

Categories