Index and Lists - Index out of range - python

Shouldn't the following code print? 100 100
price = 100 # assigns 'price' reference to 100
price = [price] # creates a 'price' list with 1 element: [100]
for i in range(1, 3):
print(price[0]) # prints 100
price[i] = price[i - 1]
price.append(price[i])
print(price[i])
Getting a IndexError: list assignment index out of range error at line price[i] = price[i - 1], but the line right before prints 100 successfully. Shouldnt price[i] simply be getting assigned price[0] value?

You're trying to append items to a list, or more precisely to initialize a list with repeated copies of something. Here are Pythonic ways to do that:
# Use a list comprehension
>>> price = [100 for _ in range(3)]
[100, 100, 100]
# Use itertools.repeat
>>> import itertools
>>> list(itertools.repeat(100, 3))
[100, 100, 100]
These are both faster than (repeatedly) doing append(), which is O(N), so repeatedly doing append() is O(N^2) on a long list, which gets very slow.
(Btw if you know a priori the list will have at least N elements, and N is large, you could initialize it to price = [None] * N and you get [None, None, None...]. Now you can directly assign to them. But, explicitly doing append is better practice for beginners.)

If you are just trying to append to a list, trying to do that with an index won't exactly work because that index isn't present in the list:
somelist = []
somelist[0] = 1
IndexError
So just use append
for i in range(1,3):
price.append(price[i-1])

The problem is you are assigning at an index too great for the length of the array.
for i in range(1, 3):
This initializes i to 1. Since arrays are zero-indexed, and the length of your array is 1 on the first pass, you will hit an assignment out of range error at the line you mentioned (when i=1).
Here is a minimal example showing the issue:
my_array = ["foo"]
my_array[1] = "bar" # throws assignment out of range error

You can't assign a value to a list directly why this list has note a previous size defined. You have to use append to add elements to the position you want.
Check:
# Check the value on our initial position
print(price[0])
for i in range(1, 3):
price.append(price[i-1])
print(price[i])

That will not print out:
100
100
You initialized a list with 1 element, the size of that list is 1. However your range starts at 1 for the for loop , what's really happening is:
price = 100 # assigns 'price' to 100
price = [price] # creates a 'price' list with 1 element: [100]
for i in range(1, 3): # The list is 0-indexed, meaning price[0] contains 100
print(price[0]) # prints 100 as it should
price[i] = price[i - 1] # i is 1, price[i] is not an assigned value, i.e: you never assigned price[1]
price.append(price[i]) # This doesn't execute because an exception was thrown
print(price[i]) # Neither does this
To get the result you're looking for, this would work:
price = [100] # creates a 'price' list with 1 element: [100]
for i in range(0, 2): # Start at index 0
print(price[i]) # Print current index
price.append(price[i]) # Append current value of price[i] to the price list
To ensure everything appended as you expected you can test it with len:
print(len(price))
Output:3
However, it is a preferred way of appending as #smci has shown in his/her answer.

Related

Terminal returns nothing

this is the challenge :
This next function will give us the values from a list at every odd index. We will need to accept a list of numbers as an input parameter and loop through the odd indices instead of the elements. Here are the steps needed:
Define the function header to accept one input which will be our list of numbers
Create a new list which will hold our values to return
Iterate through every odd index until the end of the list
Within the loop, get the element at the current odd index and append it to our new list
Return the list of elements which we got from the odd indices.
and This is my solution :
def odd_indices(lst):
odd_list = []
index = 1
while index % 2 != 0 and index < len(lst):
odd_list.append(lst[index])
index +=1
return odd_list
print(odd_indices([4, 3, 7, 10, 11, -2]))
This doesnt return [3] only . can you help me figure out why ?
You check the parity in the loop control, instead of inside the loop.

How do you replace a list of 5 0's with the first 5 even numbers? (python)

even_numbers = [0] * 5
for i in range(1,11):
if i%2 ==0:
even_numbers[i]=i
I am getting the error 'list assignment index out of range', although i'm not quite sure what that means.
"List index out of range" basically means that you are trying to access an array index that doesn't exist.
In your code, your loop goes up to 10, and you are trying to assign a number to even_numbers[10], while your array only has 5 elements. Basically you're telling your program "give me the 10th element of this 5-element list", which does not make much sense. Your indices in this case only go from 0 to 4.
To fix your issue, try storing the current index in a variable:
even_numbers = [0] * 5
current_index = 0
for i in range(1,11):
if i%2 ==0:
even_numbers[current_index]=i
current_index += 1
Edit: Alternatively, why not loop through even elements only, using the step argument of the range() function?
even_numbers = [0] * 5
current_index = 0
#will increment 'i' 2 by 2, i.e. i will be 2, then 4, then 6, ...
for i in range(2,11, 2):
even_numbers[i/2]=i
current_index += 1
The message means that you are trying to access an element of the list which does not exist.
The list only has five elements with indices 0 to 4. Trying to assign a value to even_numbers[i], you will try to assign a value to all elements of the list in the range of 1 to 10. That's why you should change the indexing to even_numbers[i/2]
The simplest solution is to generate the list of even numbers in the first place.
even_numbers = list(range(1,11,2))
If, for some reason, you already have the list, it's doesn't really matter what the original contents are if you are just going to replace them.
for i, _ in enumerate(even_numbers):
even_numbers[i] = 2*i
or just even_numbers[:] = range(1, 11, 2)

Generating a list of random integers in python 3

I am getting a IndexError: list assignment index out of range error when trying to run this program. My index appears to be fine (0 through 8) and I don't think .append is needed since the equal sign assign the random value each pass. What am I missing?
import random
#The main function.
def main():
#Welcome message.
print("Welcome to the lottery number generator program!")
print()
#Explain what the program does.
print("Note: This program will randomly generate a 7 digit lottery number and display it to the screen. ")
print("________________________________________________________________________________________________")
print()
print()
#Call the generateNumbers function and store its returned list in variable lotteryNumbers.
lotteryNumbers = generateNumbers()
#Call the printLottery function and pass the lotteryNumbers list as argument.
printLottery(lotteryNumbers)
#The generateNumbers function generated 7 random digits between 0 and 9 stores them in a list and returns the list.
def generateNumbers():
#A list variable to hold empty list.
lotteryNumbers = []
#Declare and set loop counter to 0.
index = 0
for index in range (0,8):
lotteryNumbers[index] = random.randrange(0,10)
index += 1
return lotteryNumbers
def printLottery(lotteryNumbers):
print("Here are the 7 lucky numbers: {}".format(lotteryNumbers))
#End main
main()
Lists are not like arrays in other languages!
lotteryNumbers is initialised as an empty list. There is nothing in it. Its length is zero. You need to add random.randrange(0, 10) to the empty list. This is done through .append()
for index in range (0,8):
lotteryNumbers[index] = random.randrange(0,10)
index += 1
This doesn't do what you're hoping it does. You can't assign a value to a position that doesn't currently exist in a list, and as that list is currently empty, that means you can't do this at all.
what you want is:
for index in range (0,8):
lotteryNumbers.append(random.randrange(0,10))
You don't need index += 1 because python handles this for you int the for loop.
by the way, lotteries are generally picked without replacement, so don't you actually want to sample?
https://docs.python.org/2/library/random.html#random.sample
eg:
lotteryNumbers = random.sample(xrange(10), 7)
although it is also normal for lotteries to have far more than 10 options!
By initializing an list with
lotteryNumbers = []
it has exactly 0 elements. But with
lotteryNumbers[index] = random.randrange(0,10)
You try to access the 1st, the 2nd, .. , nth element of the list. Your code does not insert elements to the list. To avoid this there are serveral approaches.
Create a dict instead of a list. A dict actually creates nonexistent elements: lotteryNumbers = {}
Preinitialize the list with 8 elements:
lotteryNumbers = [0,0,0,0,0,0,0,0]
or lotteryNumbers = list(range(8))
But the most preferable variant should be to use append:
lotteryNumbers.append(random.randrange(0,10))
You should append the new values:
def generateNumbers():
#A list variable to hold empty list.
lotteryNumbers = []
#Declare and set loop counter to 0.
index = 0
for _ in range (0,8):
lotteryNumbers.append(random.randrange(0,10))
return lotteryNumbers
or build the list up to the size you want:
def generateNumbers():
#A list variable to hold empty list.
lotteryNumbers = [0]*8
#Declare and set loop counter to 0.
index = 0
for index in range (0,8):
lotteryNumbers[index] = random.randrange(0,10)
return lotteryNumbers
Also notice you dont neet to increment the index, you are already iterating through the range.
You are trying to access non-existing elements of the list.
To build your list, you can either keep appending to it with list.append():
lotteryNumbers = []
for _ in range(8):
lotteryNumbers.append(random.randrange(0,10))
or, as it's common in Python, use a list comprehension:
lotteryNumbers = [random.randrange(0,10) for _ in range(8)]
which is usually more efficient and succinct.
I thinks you try add element to array like
lotteryNumbers = [0,0,0,0,0,0,0]
This works. Make an array with the numbers you want and select randomly one item. Then, delete that item and decrease the length with one (using pop). In this example the numbers 1 till 7
lotteryNumbers = []
rij = []
for i in range(aantal):
rij.append(i)
for j in range(7):
r = random.randrange(0,7-j)
k = rij.pop(r)
lotteryNumbers.append(k+1)
print(lotteryNumbers)

How to print items from list that haven't been printed?

My question is, how to print only items that haven't been printed?
(it's just part of the code).
I have an array of 15 items that has to be shuffled, then print only the quantity that e/2 is. I've tried by making a second list with the indexes of the items from the array and then printing only the indexes and items that are present on my list. If an index is not on my list then it will not be printed. After every print the index of the item is removed from my made up list so it won't be printed for the second time.
def tryitem(self,c,list1):
if c not in lista:
c = random.randint(0, 14)
self.tryitem(c,list1)
else:
pass
...some code...
list1 = list(range(15))
for i in range(int(e/2)):
c = random.randint(0, 14)
print(c)
self.tryitem(c,list1)
but= ttk.Button(root, text=str(item.myItem[c][0])+" x"+str(item.myItem[c][1]))
but.place(anchor=W,x=20,y=wysokosc,width=170,height=25)
wysokosc+=25
list1.remove(item.myItem[c][2])
indexes of the items are at myItem[c][2] column
First of all this method doesn't work as it should, because it is printing some items two to three times, and after some prints I get the error
ValueError: list.remove(x): x not in list
I'll try answering your first question, assuming you have a list and you want to print it's items in some kind of iteration, and you want to keep track on what items has been printed already in order to not print them again.
The easiest way is to use a dictionary.
Every time you print an item, add his index to the dictionary.
Every time you want to print an item, check if his index is in the dictionary, and print only if it does not.
import random
e = random.randint(1, 30)
lst = [random.randint(1, 1000) for _ in range(100)]
printed = {} # To save if we perinted this index already
def print_next_values():
for x in range(int(e/2)): # print (e/2) items
index = random.randint(0, len(lst) - 1)
# Try to fetch new indexes until we get a new index we havn't printed yet
while index in printed:
index = random.randint(0, len(lst) - 1)
print(lst[index]) # Printing the item
printed[index] = True # Adding the item index to the dictionary
while len(printed.keys()) < len(lst):
print_next_values()
Here you can see a list of 1000 items, that will be printed in parts (e/2 every iteration, until there is no more items).
Before we print an item, we check if he has been printed already. If not, we print it.

IndexError: list assignment index out of range for arrays

I am new to python. I think n begins at 0 and it will increase up till the last element on stack1.
arraylength = 3*stack1length
array = [0]*arraylength
for n in stack1:
array[3*n] = stack1[n]
my array length is 3 times the length of stack1
for n in stack1:
Goes through the items in stack1.
You seem to be wanting to go through the indexes:
for n in range(len(stack1)):
array[3*n] = stack1[n]
Note that this is better written with the convenience function, enumerate,
for n, stack1_n in enumerate(stack1):
array[3*n] = stack1_n
Additionally, you can use some evil hackz:
array[::3] = stack1
array[::3] is every third item in array (start:stop:step), and therefore you're setting every third item to the corresponding item in stack1.

Categories