Python: Int is object is not subscriptable - python

I know this is a topic that there are already several threads for. I've reviewed them and understand what this error means, but for some reason cannot get it to work for my code.
I'm trying to code a simple Python function that takes a list of integers as input and outputs the integers in the list that are exactly twice the amount of the previous integer in the list. Here is the code I have so far:
def doubles(lst):
i = -1
for num in lst:
if num == num[i + 1] / 2:
print(num)
Now I know the issue is that it is trying to print this integer as a string. I have tried editing the codes last line to say print(str(num)) and that does not work, nor does changing my if statement in line 4. Any assistance would be greatly appreciated!

if num == num[i + 1] / 2:
should be
if num == lst[i + 1] / 2:
Also, I recommend using enumerate to iterate over the list with indexes, but there are better ways of doing such a thing, as shown in galaxyan's answer

you can zip original list and list begin from second element,then compare two elements
def doubles(lst):
return [ i for i,j in zip(lst,lst[1:]) if j==i*2 ]
example:
lst = [1,2,3,5,66,2,4,5]
print doubles(lst)
[1, 2]

You're attempting to subscript an item in the list, not the list itself. Instead of iterating the items, you could iterate the list's indexes:
def doubles(lst):
for i in range(0, len(lst) - 1):
if lst[i] == lst[i + 1] / 2:
print(lst[i])

Related

Output the index of an item in a set in Python/Sage

This is what I have so far.
def f(n):
my_list=[]
while n not in my_list:
my_list.append(n)
if n % 2 == 0:
n = n / 2
else:
n = 3 * n + 1
my_list.append(n)
return my_list
The above code takes any input n and outputs a list e.g. f(2) -> [2, 1, 4, 2]
Now I want to look at any range and output just the highest element in said list.
def f_2(i):
for i in range (1,101):
set_f = set(f(i))
print(max(set_f))
So I converted the list to a set and applied the max command to it. All of this has worked as I had intended it so far.
My problem is with the following issue:
I want to output all the indexes of all the highest Elements in all generated lists.
E.g. for i in range (1,101): The highest Element is 9232. I tried doing it in the above way, but a set does not have any indexes. However max() does not seem to work on a list of generated lists.
My try was:
def f_3(i):
for i in range (1,101):
set_f = set(f(i))
if max(set_f) == 9232:
print(set_f.index(9232))
else:
pass
Here I get the error that set has no index attribute.
def f_3(i):
for i in range (1,101):
if max(f(i)) == 9232:
print(f.index(9232))
else:
pass
Here I get the error that function has no index attribute.
Only the range of 1 to 100 is of interest to me. So I can use 9232 as a value.
Any help would be greatly appreciated, I feel a bit stuck on this one.
There's several things to unpack here, and I feel like the Code Review community would be a better fit.
First of all, why does f_2 have the parameter i? You're just using the i from the loop.
Second, why are you converting the list into a set at all? max works just fine on lists too.
set doesn't support indexing, and that's why you were getting that mistake.
At the other attempt with f_3, you've called index on the function f instead of f(i).
Function f_2 can be rewritten as such.
def f_2():
for i in range (1,101):
lst = f(i)
mx = max(lst)
print(lst.index(mx))
Function f_3 is inefficient, but it too can be fixed like this:
def f_3():
for i in range (1,101):
if max(f(i)) == 9232:
print(f(i).index(9232))

bubble sort in python:index out of range

I am new to python and I was trying out bubble sort. Not able to find the error.
Little help here.
def bubble(n, list):
for i in range(0, n):
for j in range(0, n - i - 1):
if list[j] > list[j + 1]:
list[j],list[j+1] = list[j + 1],list[j]
def main():
n = input('size')
n = int(n)
list = []
for i in range(0, n):
no = input('no')
list + [no]
bubble(n, list)
print(list)
main()
During execution, it's showing:
line 4, in bubble
if (list[j] > list[j + 1]):
IndexError: list index out of range
But I couldn't find out how. The index always will be
The first problem is that you don't convert the input('no') to int. It is not the cause of the current problem, but would cause problems later.
The second problem is that you use list as a variable name. list is a predefined Python class and you will overwrite it. Choose a different name.
The third problem is that you use list + [no]. That will not add no to list. It would just store the output temporarily and delete it automatically. There are 2 solutions:
1. Using +=
a += b is equal to a = a + b. This is also the case for many arithmetical operators. Just replace + with +=.
2. Using append
append is faster. Use it like somelist.append(somevalue).

List index out of range error while performing a binary search

I attempted to create a function that takes an ordered list of numbers and a given number, and decides whether or not the given number is inside the list. I am trying to use a binary search to accomplish this task.
I have two steps:
First, I am making list1 smaller by only taking the numbers in list1 that are smaller than the given number, and then appending those numbers into a new list, called newlist.
Next, in the while loop, I am basically taking all the numbers that are less than the number in the middle of the newlist and removing them, repeating that process multiple times until there is only one number in newlist. From there, I would compare that number to the given number. My code is shown below.
list1 = [1, 3, 5, 6, 8, 14, 17, 29, 31]
number = 7
def func(list1, number):
newlist = []
for x in list1:
if x < number:
newlist.append(x)
else:
continue
while len(newlist) > 1:
for x in range(0, len(newlist) - 1):
if newlist[x] < newlist[round(len(newlist) / 2)]:
newlist.remove(newlist[x])
else:
continue
if newlist[0] == number:
return True
else:
return False
print(func(list1, number))
I am receiving an error at line 36 (if newlist[x] < newlist[round(len(newlist) / 2)]:), that the list index is out of range. I think that the problem is that as newlist is getting smaller and smaller, the x value set by range(0, len(newlist) - 1) is staying the same?? If that is the case, I am unsure of how to remedy that. Much thanks in advance.
The issue is this bit right here:
for x in range(0, len(newlist) - 1):
if newlist[x] < newlist[round(len(newlist) / 2)]:
newlist.remove(newlist[x])
First, you're iterating over the list
[0, 1, 2, ..., len(newlist) - 1]
This list is generated when you start the loop, meaning that if len(newlist) is 7 at the beginning, the list will always go up to 6, regardless of whether things are removed from newlist, which you later do. This is what causes your error, since at some point you've removed enough elements that your list is now, say, three elements large, but python is trying to access the fifth element because the list it's iterating over isn't newlist, it's [0, 1, 2, 3, 4, 5, 6].
To fix this, you could (for example) replace the for loop with this:
x = 0
while x < len(newlist - 1):
if newlist[x] < newlist[round(len(newlist) / 2)]:
newlist.pop(x) # simple way of saying "remove item at index x"
This is essentially the way of doing a C or Java-style for loop in python, and will avoid this type of problem.
I also understand that you have an issue with the logic in your code, which was pointed out in one of the comments above and gets more to the heart of your underlying issue, but this is at least an explanation of why this error occurred in the first place, so maybe it's helpful to you in the future

To find duplicates in a python list, why doesn't this logic work?

While I am aware that the best and simplest method to find duplicates in a list is by using Collections.Counter, I wish to know where does the following logic fail.
def uniquenumbercheck(listarg):
for i in range(2,len(listarg)):
for j in range(1,i-1):
if(listarg[i]==listarg[j]):
print("duplicate value appeared : "+str(listarg[i]))
return
print("all entered values are unique. ")
The program is running but failed to display the correct output.Could not figure out the mistake.For the example input of 1,1,0 integers to list, it says that they are unique.
Off-by-one error. In Python, indexes start at 0, not 1. So,
for i in range(2, len(listarg)):
for j in range(1, i - 1):
should be:
for i in range(1, len(listarg)):
for j in range(0, i):
Also, range(1, len(listarg)) can also be written as range(len(listarg)).
i am assuming you are searching for duplicates within a list:
myl = [1, 2, 3, 5, 6, 1, 2]
for i in myl:
if myl.count(i) > 1:
print i
where the duplicates are printed out.

Need help to find python code bug

def remove_adjacent(nums):
i = 0
while i < len(nums):
if nums[i] == nums[i+1]:
nums.remove(nums[i])
i = i + 1
else: i = i + 1
return nums
IndexError: list index out of range
Who can tell me what's wrong with my code?
There are several issues with your code.
As AbhiP points out, you're looking at pairs of consecutive items in your list - there are len(nums)-1 pairs that you should be comparing, but you're trying to compare len(nums) pairs. That's one cause of the index error.
Secondly, as John mentions, you're removing items in your list while you loop through it. If you really want to keep your current structure, you need to not increment the loop variable when you remove an item.
Correction/Clarification: This second point won't cause an index error, but it will cause bugs by making the code skip the evaluation of certain pairs, e.g. for inputs such as [1, 1, 1, 2].
Taking these two points into consideration, your code will look like:
i = 0
while i < len(nums) - 1:
if nums[i] == nums[i+1]:
nums.remove(nums[i])
else:
i += 1
Which will remove the index error.
Thirdly, nums.remove(nums[i]) will also cause non-index error bugs. Try the above code with nums being [1, 2, 3, 1, 1]. You will see that the first 1 is removed, not the 4th or 5th item in the list. This is because remove on a list gets rid of the first instance that appears in the list. You should probably do del instead, as below:
i = 0
while i < len(nums) - 1:
if nums[i] == nums[i+1]:
del nums[i]
else:
i += 1
Finally, while not a bug, best practice would suggest that you shouldn't modify a list while looping through it - this makes the code hard to reason about, and can lead to subtle bugs. Instead it's usually better if you just create a new list and return that.
new_nums = []
for i in range(len(new_nums)-1):
if nums[i] != nums[i+1]:
new_nums.append(nums[i])
new_nums.append(nums[-1])
An alternative way of writing this using zip and list comprehensions, two of Python's cool features:
new_nums = [item1 for item1, item2 in zip(nums, nums[1:]) if item1 != item2]
new_nums.append(nums[-1])
Your problem is the line while i < len(nums):. It will iterate from 0 till len-1 but the next line you are doing if nums[i] == nums[i+1] so the index will go until len.
Change it to:
while i < len(nums) - 1:
You are removing items from the list while iterating through it. The for loop has no idea that the bounds have changed, thus the error.

Categories

Resources