Replace item in list upon negative index as input - python

Currently, I have a list as such:
aList = [1,2,3,4,5]
and what I'm trying to do is to emulate 'aList[index] = item' function in python. the program prompts the user for input of negative index and the item to replace.
enter negative index: -2
enter item to replace: 7
this would give me:
[1,2,3,7,5]
since, when the index is negative, python starts counting from the back of the list. Here's my code:
aList = [1,2,3,4,5]
index = int(input("Enter index:"))
item = int(input("Enter item:"))
j = -1 #-1 means the counter should begin with -1 not 0
start = len(aList)-1 #i want python to start from the back of the list
while j<start:
if j == index:
aList[j] = item
j-=1
print(lst)
I'm getting an infinite loop because of the j-=1 and I'm wondering if I'm emulating it correctly?

I think first you need to clear you concept about array.
What is Array.?
Arrays a kind of data structure that can store a fixed-size sequential collection of elements of the same type. An array is used to store a collection of data, but it is often more useful to think of an array as a collection of variables of the same type.
Instead of declaring individual variables, such as number0, number1, ..., and number99, you declare one array variable such as numbers and use numbers[0], numbers1, and ..., numbers[99] to represent individual variables. A specific element in an array is accessed by an index.
All arrays consist of contiguous memory locations. The lowest address corresponds to the first element and the highest address to the last element.
Array In Python
To define a list you simply write a comma separated list of items in square brackets:
myList=[1,2,3,4,5,6]
This looks like an array because you can use "slicing" notation to pick out an individual element - indexes start from 0. For example
print myList[2]
will display the third element, i.e. the value 3 in this case. Similarly to change the third element you can assign directly to it:
myList[2]=100
The slicing notation looks like array indexing but it is a lot more flexible. For example
myList[2:5]
is a sublist from the third element to the fifth i.e. from myList[2] to myList[4]. notice that the final element specified i.e. [5] is not included in the slice.
Also notice that you can leave out either of the start and end indexes and they will be assumed to have their maximum possible value. For example
myList[5:]
is the list from List[5] to the end of the list and
myList[:5]
is the list up to and not including myList[5] and
myList[:]
is the entire list.
List slicing is more or less the same as string slicing except that you can modify a slice. For example:
myList[0:2]=[0,1]
has the same effect as
myList[0]=0
myList[1]=1
Finally is it worth knowing that the list you assign to a slice doesn't have to be the same size as the slice - it simply replaces it even if it is a different size.

I am not sure why you need a loop, when you can just access the elements by index:
aList = [1,2,3,4,5]
index = int(input("Enter index:"))
item = int(input("Enter item:"))
aList[index] = item

Of course your loop is infinite...the variable 'j' keeps getting more negative and you're comparing it so 'start', which is the length of the list minus one.

Related

How to clear an Array in Python?

I am trying to create an array and then clear it using a function, but the terminal keeps displaying 'list index out of range'.
duplicates = []
def ClearArray():
for index in range(100):
duplicates[index].append("")
ClearArray()
print(duplicates)
The instruction is to Initialise the global array Duplicates, which is a 1D array of 100 elements of data type STRING, and set all elements to empty string using a function.
You are getting the error because you are initializing an empty list and then trying to access elements inside of that list.
In the first iteration of the for loop, you attempt to access duplicates[0] but the list is empty, and therefore the list index out of range exception is raised. You can resolve this by replacing duplicates[index].append("") with duplicates.append("").
You can read more about python lists here.
In addition, according to python's PEP8 function names should be lowercase, with words separated by underscores as necessary to improve readability.
Putting it all together:
duplicates = []
def clear_array():
for index in range(100):
duplicates.append("")
clear_array()
print(duplicates)
To remove all elements of a list, you can use clear, like so:
duplicates.clear()
I am not sure what you mean by clear, but when you create a list/array in python it will not have data
In case you need to add some data
duplicates = []
print(len(duplicates)) # length should be zero
for i in range(100):
dupicates.append(i)
In case you need to clear all the data in the list
print(len(duplicates)) # Should print 100 from the above for loop
duplicates.clear()
print(len(duplicates)) # Should be 0 again considering we have cleared the data
In case you are trying to create an array of arrays
duplicates = [[]] * 100
print(duplicates) # should show you 100 lists in a list
You are trying to get something that doesn't exist.
Your list duplicates = [] has nothing in it. Therefore duplicates[0] does not exist, which is why you are getting list index out of range.
In your example:
def ClearArray():
for index in range(100):
duplicates[index].append("")
The first iteration of your for loop accesses duplicates[index] where index = 0, Which throws the error.
When you append, you add to the end. So there is no need to specify an index. So this below will work fine:
def ClearArray():
for index in range(100):
duplicates.append("")
First create a non-empty array.
Then repeat deleting the first item of this array as many times as there are items in your array.
array = [43,54,65,76]
def ClearArray(array_to_clear):
for index in range(len(array_to_clear)):
del array_to_clear[0]
ClearArray(array)
print(array)
If you don't want to delete the items of the list but you want to replace each item with an empty string, then i recommend this code :
array = [43,54,65,76]
def ClearArray(array_to_clear):
for index in range(len(array_to_clear)):
array_to_clear[index] = ""
ClearArray(array)
print(array)

How can I sum pairs of numbers in a list and if the sum is equal to another element in the list, how can I remove this element from the list?

I have a list of numbers:
nums = [-3,-2,-1,1,2,3,0,0]
And I want to iterate over the list, and add two numbers at a time, and if the sum of these two numbers is an element in the list (excluding the two we just summed), then I want to remove the element. How can I do this?
For example, since -3+2= -1 and -1 is in the list, I can remove -1 from the list.
I tried to create an empty list/set to store the sums of each pair of elements, then compare the elements in nums to this list/set, but this doesn't work, as it violates the second part of what I want to do- in brackets above!
P.S. I would like to remove as many elements as possible, and one worry is that if I remove elements as I iterate the list- before finding all of the pair sums- then I might miss some valid pair sums!
Any help is much appreciated.
Although possibly inefficient (didn't care about efficiency when writing this answer), you could probably do the following:
for first in nums[:]:
if first == 0: continue
for second in nums[:]:
if second == 0: continue
sum = first + second
if sum in nums:
nums.remove(sum)
There are 2 things I will go over in this answer;
nums[:] is the slicing syntax that will just create a copy of the array, whereafter that copy will be iterated over. The syntax for this was found within this answer: https://stackoverflow.com/a/1207461/6586516
There are also checks to see if either the first or second number is equal to 0. This will satisfy the second condition (according to my logic). The only time the sum of a set of numbers can be equal to itself/one of the numbers used in the addition is when n - 1 numbers is equal to 0 (where n is the amount of numbers used in the addition)
You could try something like this:
itertools.combinations returns us with all possible combinations of a the argument. Since you want to numbers, providing 2 as the argument will return all possible combinations with length 2
Then we will just check the conditions and proceed to remove from the list.
from itertools import combinations
nums = [-3,-2,-1,1,2,3,0,0]
nums2=[i for i in combinations(nums,2)]
print(nums2)
for i in nums2:
sums=i[0]+i[1]
if sums in nums and (sums!=i[0] and sums!=i[1]):
try:
print(f"{sums} removed from list.\nNew List: {nums}")
nums.remove(sums)
except ValueError:
print("{sums} not in list")
print(nums)

Re-generate a random index until the indexed element is met the condition n times in python

I know there have been a few similar questions regarding loop and random numbers, but I can't seem to find a solution for my problem.
Say I have a fixed list of numbers from my dataset and a threshold that the number has to meet:
x = (7,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41)
threshold= 25
I need to randomly pick a number from this list. Unfortunately, I cannot just directly loop over my original list, I'm forced to randomly pick an index of the list first, and find my number. So for example if I now randomly generate a index number 1 then I get x[1] which is 11
The final result I need is to find numbers that are greater than the threshold for at least 3 times and then put all the resulting number in a list, then my loop can stop. (The indexes cannot repeat).
As an example, a possible final results would be (27,29,31) (The results can be in any format) . I'm thinking maybe something like this to start but really need help to proceed:
Unless you are particularly concerned about the memory usage of creating an additional filtered list, the simplest would probably be to start by doing this:
filtered = [i for i in x if i > threshold]
You can then choose three samples from this filtered list (after import random). The following will potentially choose the same item more than once:
random.choices(filtered, k=3)
or if you want to avoid choosing the same item more than once:
random.sample(filtered, k=3)
Each of the above functions will output a list. Use tuple(....) on the output if you need to convert it to a tuple.
First a clarification. Do you need to pick a random element from the list each iteration, or do you need to pick a different random element from the list each time. I.e., can the same index be picked twice? You're doing the latter.
Second, you want to use range(len(x)). You don't want to hardwire the length of x into your code, and you want index 0 to be a possibility. random.shuffle() may be a better choice.
Lastly, you want to do something like:
result = []
for ....
if select >= threshold:
result.append(select)
if len(result) >= 3: break
If we assume the following constraints:
We are not allowed to loop over the original list (including list comprehension)
We are only allowed to access one member of the original list at a time through its index
We must pick 3 distinct members of the list that are greater or equal to the threshold
The following code should satisfy all of them:
x = [ 7,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41 ]
threshold = 25
result_index = []
while len(result_index) < 3:
index = random.range(0, len(x))
if x[index] >= threshold and index not in result_index:
result_index.append(index)
result = [ x[a] for a in result_index ]
Here is how this works:
In the loop, we store indices, not the numbers them selves.
For each index we check 2 conditions: there is a number there that is bigger or equal to the threshold and we haven't seen this index before.
If the conditions are satisfied, we save the index, not the number!
Repeat until we have 3 indices.
Build new list by getting numbers from those indices directly.

when assigning to a variable list index out of range?

n = int(input())
numb = input()
lis = list(map(int, numb.split()))
lis.sort()
a = lis[n]
for i in (0,len(lis)):
if lis[i]=[a]
print (lis[i-1])
I tried this and when I enter input of 5 for n and the lis as 24689 it says there is an error in the line where a=lis[n] saying the list index is out of range.
The problem is probably with the line
for i in (0,len(lis)):
Lists are zero-based so the valid indexes are from 0 to len(lis) - 1. len(lis) is indeed out of range.
Also, notice that the above line of code means that i will receive only 2 values - 0 and len(lis). Is that what you really mean? If you meant to go over all the indexes, you will need to do
for i in range(len(lis)):
range(n) is an iterator that returns the values from 0 to n - 1.
There are several problems with this code. Firstly, you need to change your for statement to for i in range(0, len(lis)) because you're not currently calling the range function.
Also, on the first iteration, it will try to access index -1, which is the last element in the list. A better idea is to change your range function to range(0, len(lis) - 1), and changing the print statement on the last line to print(lis[i]) to fix the problem of receiving the last element by using the index -1.
P.S. Welcome to Stack Overflow!
Wow, Keep note that what you thought would happen on your third line wasn't the case and is 1 of the 2 problems of your error message. and that 1 problem was due to one single function you used which I have sequentially demonstration below;
I assume you were expecting each character of the string '24689' to be transformed to an integer by the map() function*, then converted to a list by the list() function*, then stored in the Variable ...lis... for later further usage. You were expecting something like [2,4,6,8,9] as Lis`.
Well you almost had that if not for your decision to use split() on Numb.
The Split function will run first and turn the '24689' into a
different iterable, in this case changing '24689' to a list ['24689'].
Then the map() will map every item in this iterable ['24689'] to an
integer. In this case only 1 item exist in the list which is '24689'.
So it maps that item as an integer.
Then the list() function stores this single item which is now an
integer in a list owned by the variable Lis. So you finally get
[24689]. And this is different from your [2,4,6,8,9] expectation.
As I've demonstrated above, so the cause of all this problem was your decision to use Split().
if you take away the split(), then;
the map() will no longer see just one Item but rather '2' '4' '6' '8'
'9' because a string '24689' is an iterable, with 5 individual items in
your case. So the map() runs over all these 5 items in your Numb string and
maps/transforms them to individual integers respectively. Then finally
the List() would have stored all these beautiful individual integers
in a list Owned by the variable Lis.And you get your desired [2,4,6,8,9] in return for the Variable Lis.
So the correct statement for that very line is:
lis = list(map(int, numb)) // This line should now produce [2,4,6,8,9]
The second problem of your error was the value you assigned to the index variable 'n' of list[n]. I assume you wanted to fetch the fifth item in the list. This 'n' is the linear count of items(in your case the individual numbers - 2,4,6,8,9). This counting start from 0 for the first letter instead of 1. Normally when you count items, the first letter is 1 but for index count in python list[n], the first letter is 0 instead of 1 so in your case the fifth item will be indexed as 4 since index count start from 0. So your 'n' input should be 4
These 2 solutions above solves your the specific error you mentioned.
BUT aside from your question above, your entire code will still run into another error even if the above solutions are implemented. This is Due to errors on these following lines as well:
On line 6:
for i in (0,len(lis)): //Wrong due to NO function name called before '(0, len(lis))'.
We will logically assume you want to use the range function
correct expression on LINE 6 is:
for i in range(0, len(lis)):
On Line 7:
if lis[i]=[a] //Three problems on this line...
First, you can't compare two objects with the operator '='. instead use '=='
Second, [a] is a meaningless value in your expression... Does comparing that to a number look right to you? I bet No. Remember [a] is not the same as the variable 'a'.
a = lis[n], while [a] = [lis[n]]
So the correct expression there should be 'a' and not '[a]'
Last, you need to add ':' after every "if", "for" or "while" expression..
Here is how LINE 7 should CORRECTLY look like,
if lis[i] == a:
All the above solutions should satisfy your need. So the complete correct code for your script should look like this:
n = int(input())
numb = input()
lis = list(map(int, numb))
lis.sort()
a = lis[n]
for i in range(0,len(lis)):
if lis[i] == a:
print (lis[i-1])

Do something for every fifth object in a list

All right, so I have a code where I need to print a game board with 5x5 squares. All the squares is in squareList, which is a list (oh you don't say). A square is based on an object with a variable number that is the value I want to print. How can I do this?
EDIT: The reason to why I want to do this is because I want to start on a new line every five squares so that I get a board, not a line, with values.
The python slice / array operator supports an optional step as the third value. squareList[start:end:step]:
for o in squareList[::5]:
print(o.number)
Use 5 as the step value to get every fifth entry in the list.
Why not make list for each row in the square, and then put those rows into a list?
squareList = [rowList1, rowList2, rowList3, rowlist4, rowList5]
This way you can manipulate a column as you loop through the rows.
for row in SquareList:
doSomething(row[4])
You can also extract a column using a list comprehension.
colList1 = [row[0] for row in squareList]
I would agree that you might want to consider other more convenient structures for your data, as suggested by CCKx.
Here are two approaches
Assuming:
squareList = [0,0,1,0,0,
1,2,0,0,1,
0,0,0,1,2,
2,2,0,0,0,
1,0,0,0,1]
Then you can do this:
for index, value in enumerate(squareList):
print(value, end='')
if (index % 5) == 4:
print()
(I'm assuming Python 3.)
That will literally do what you asked for in the way that you asked for it. index will count up through each element of your list, and the % or "modulo" operator will get you the remainder when you divide by 5, allowing you to take some action every 5 times round the loop.
Or you can use slicing:
for row in range(5):
for cell in squareList[row*5:row*5+5]:
print(cell, end='')
print()
See also:
What is the most "pythonic" way to iterate over a list in chunks?

Categories