In Python, if I want to add one element like below, what do I need to do (without using build-in-function)?
a = [0,1,2,3]
a[3+1]=4
print(a)
Traceback (most recent call last):
File "/home/cyber/Program/Python/Design Thinking/Python code/q2.py", line 18, in <module>
a[3+1]=4
IndexError: list assignment index out of range
Looks like you want to add the value 4 to the end of list a in which case:
a = [0,1,2,3]
a += [4]
print(a)
Output:
[0, 1, 2, 3, 4]
However, if you want to add a value at, say, index 5 then you can't do that without extending the list to accommodate that index and any missing ones. What are known in other languages as sparse lists (arrays) don't exist in Python. Of course you could write something yourself
Related
I'm pretty new to python and I'm stacked on a simple problem:
i have a list:
mylist = [1, 2, 3, 4]
if I extract one element like this:
print(my_list[1:2])
I get a list of one element, but i cannot compute any calculus by treating it as a variable :
print(my_list[1:2]+1)
because i get the error:
Traceback (most recent call last):
File "C:\...\test_tuple.py", line XX, in <module>
print(my_list[1:2]+1)
TypeError: can only concatenate list (not "int") to list
how do I convert this single element list to a variable?
What you are doing, with :, is slicing. This means grabbing a piece of a list as a new list. What you want is just one index, which you can do be using:
mylist = [1, 2, 3, 4]
print(mylist[2]+1)
You can also turn a one element list into a variable by using:
mylist = [1, 2, 3, 4]
new_list = mylist[1:2]
print(new_list[0]+1)
Lastly you can also use numpy arrays on which you can perform calculations as if it were a normal number as follows:
import numpy as np
mylist = [1, 2, 3, 4]
new_arr = np.array(mylist[1:2])
print(new_arr[0]+1)
of course the first solution is the best in this case, but sometimes other solutions can fit your problem better.
You're error is about, you are adding number to [],
you need to add number to number like below code;
print(my_list[1:2+1])
print(my_list[2+1])
print(my_list[2]+1) ##here youre adding to the value like (my_list[2])3+1 that it will not give you error
I'm doing an exercise where a function takes a list and an integer n and deletes every element if its index i satisfies (i+1)%n==0. Here's what I've come up with:
def f(lst, n):
for i in range(len(lst)):
if (i+1)%n==0:
del lst[i]
However, it gives me this error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "pop.py", line 4, in f
del lst[i]
IndexError: list assignment index out of range
The index pointer i doesn't seem to be able to run out of range? What causes this to happen?
What data set are you using?
Depending on the numbers in your data set, the problem is that you're deleting objects from your list, creating a conflict when you ask for a specific index in that list.
ex_list = [2, 5, 12]
print range(len(ex_list))
output [0, 1, 2]
So lets say the first item doesn't pass your test and gets deleted. Now oyur list looks like this:
ex_list
>>>[5, 12]
The problem is that your next i in your for loop will be 1 but now:
ex_list[1]
>>>12
and ultimately:
ex_list[2]
>>>IndexError: list assignment index out of range
What is happening is that when you are deleting an element from a list, your list size is changing.
You don't have to iterate over the list to find the the indexes that is divisible by n.
for e.g. if list_length = 8 and n = 2, then we know the element#[2,4,6,8] = index[1,3,5,7] have to deleted. You can just create a filter here or list comprehension like this will also do-
new_list = [old_list[i] for i in range(len(old_list_length)) if (i+1) % n == 0]
old_list = new_list
Note :- You can note iterate over a list, where a element have been deleted, since the original element you like to delete, will now have different index. Going with the example in the start of answer:-
lets say you have deleted element#2(index = 1), Now subsequent element#4,#8 will now become element #3, #7, so now you cannot track the original elements you wanted to remove the list.
This question already has answers here:
Understanding slicing
(38 answers)
Closed 6 years ago.
i have added one list like below:
>>> l = [1,2,3,4]
>>> len(l)
4
so when i accessed
l[3:1] python has return blank list like []
l[3:1]=4 it returns error like
>>> l[3:1] = 4
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only assign an iterable
but when i used l[3:1] = 'a'. it successfully run and gives new list as below:
>>> l[3:1] = 'a'
>>> l
[1, 2, 3, 'a', 4]
>>>
now i have length of 5. now i want to add new element at 5th index so i write
>>> l[5] = 5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range
>>>
my questions are follow:
why ptyhon returns blank list when accessing like l[3:1]?
why it gives error when using l[3:1] = 4 but works fine using l[3:1]='a'?
Why it is giving error instead of adding new value at 5th index?
why python returns blank list when accessing like l[3:1]?
list[i:j] means you want sliced list with value from 'i'th index to upto 'j'th index (not including jth index). For example:
>>> my_list = [1, 2, 3, 4, 5]
>>> my_list[2:3]
[3]
In your case i > j, hence list is empty.
why it gives error when using l[3:1] = 4 but works fine using l[3:1]='a'?
l[3:1] is the sliced list. You can a assigned it only with list. since, python str are considered as the list of chars. That is why you are able to assigned it.
Why it is giving error instead of adding new value at 5th index?
Even though the length of your list is 5 but since the index of the list starts with 0, you can access element of list only till len(list) - 1. In case you want to add item at the end of list, you need to do .append() on the list. Below is the example to show this:
>>> my_list = [1, 2, 7, 9, 8, 4, 5]
>>> len(my_list)
7 # <-- Length as 7
>>> my_list[6]
5 # <-- value of index at length(list) - 1, which is the last value of list
>>> my_list[7] # <-- index as length of list, resulted in 'IndexError'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
>>> my_list.append(9) # <-- Adds an item at the of list
>>> len(my_list) # length incremented by 1
8
as l[3:1] is a Sequence hence you can assign only a Sequence to it thus,
the reason l[3:1] works because 'a' itself is a sequence but 4 is a normal integer.
Why does python return a blank list when accessing like l[3:1]?
Slicing works as follows:
l[start:end] # start to end-1
l[start:] # start to rest of list
l[:end] # beginning of list to end-1
l[:] # copy complete list
As you are passing l[3:1] i.e start from 3rd index and end at 1-1 i.e 0th index, that means start index > end index, so empty list will be displayed. Either you can pass l[1:3] or any negative indexes (ex: l[-3:-1]).
Why does it throw an error when using l[3:1] = 4 but works fine using l[3:1]='a'?
In slicing retrieval, you will get a list (sequence)
In same way, in case of slicing assignment, you can pass sequence. Here string is sequence of characters and so working for string and not for integer
In case of integer, you can try:
l[3:1] = [4]
Why does it throw an error instead of adding new value at 5th index?
list contain only 4 elements. l = [1,2,3,4]
Here, you can not access or assign more than index 3 (index starts from 0).
In your scenario, you can append data.
First question - You are trying to slice the list from two different ways.
Given l = [1, 2, 3, 4]
l[3:] slices the list from element with index 3 and onwards, leaving you with [4]
l[:1] slices the list from element with index 1 and backwards, leaving you with [1].
Now if you slice it both ways, you will have an empty list, there's nothing in that range.
Second question - this one is kind of odd. In theory string behaves like a list with each character being an item in that list, so that's why you can only enter 'a' and 4 being an integer throws an error. I don't exactly know why, but [3:1] inserts the new list (characters of the string) after 3rd element. If you leave out the [:1], it will replace the list from 3rd element instead, leaving you with [1, 2, 3, 'a']
Third question - You can only access indexes of a list that already exist. 5th index doesn't exist for you yet. You have to create it. That's either by append, insert etc. Then you can modify it with l[5]
i am trying to pick 7 numbers at random out of a list on 10, i have written the following code to help me do that :
s=set(range(1,10))
import random
i = []
while len(i)<8:
s.remove(random.choice(list(s)))
i.append(s)
print i
an important point of this is the number is removed from the group to prevent it being picked twice
however when i run the code i get the error :
Traceback (most recent call last):
File "randomTest.py", line 7, in <module>
s.remove(random.choice(list(s)))
File "/usr/lib/python2.7/random.py", line 273, in choice
return seq[int(self.random() * len(seq))] # raises IndexError if seq is empty
IndexError: list index out of range
What is causing the error and how do i fix it ?
Don't reinvent the wheel. What you are looking for is random.sample -
>>> s=set(range(1,10))
>>> import random
>>> random.sample(s,7)
[7, 5, 6, 8, 9, 3, 4]
Though this working on set actually seems like an implementation detail (and may not work for sets with more than 21 elements) because random.sample internally converts the iterable (first argument) it receives into a list at https://hg.python.org/cpython/file/c6880edaf6f3/Lib/random.py#l330. It would be better to not rely on this implementation detail and manually convert the set/sequence to a list or sequence -
>>> s=set(range(1,10))
>>> import random
>>> random.sample(list(s),7)
[6, 8, 4, 2, 5, 9, 7]
From documentation -
random.sample(population, k)
Return a k length list of unique elements chosen from the population sequence. Used for random sampling without replacement.
And as mentioned in the comments, you may not really need a set here.
You code should not produce IndexError: list index out of range, since in your example s contains 10 elements, and you choose 7.
Maybe this exception was raised while executing this code on a different set.
However, you should fix a bug that will prevent you from seeing the results you seek:
Each time, you are appending all of s into i, what you want is to append only the chosen value.
Suggestion:
s=set(range(1,10))
import random
i = []
while len(i)<8:
chosen = random.choice(list(s))
s.remove(chosen)
i.append(chosen)
print i
This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 9 years ago.
I'm practicing my progamming skills by solving problems from project euler at the moment, and now I've come across some (in my opinion) strange behavior on Python.
When I do:
list = [[1]]*20
I get a list of 20 lists containing element 1, as expected. However, when I would like to append a 2 to the third element from this list, I would do that as follows:
list[3].append(2)
This however changes ALL the elements in the list. Even when I take a detour, like:
l = list[3]
l.append(2)
list[3] = l
All my elements get changed. Can anyone please tell me how to do this and get an output like so:
[[1], [1], [1], [1, 2], [1] .... [1]]
Thanks in advance.
Python lists are mutable objects, so when you do [[1]]*20 it creates one list object [1] and then places 20 references to it in the toplevel list.
As far as the mutability problem is concerned, this is the same as the following
a = [1,2,3]
b = a
b.append(4)
a # [1,2,3,4]
This happens because b=a merely copies the reference to the list instance from a to b. They are both referring to the same actual list.
In order to create a list of lists, like you tried above, you need to create a unique list for each entry. A list comprehension works nicely:
mainlist = [[1] for x in range(20)]
mainlist[0].append(2)
mainlist # [[1,2],[1],[1],...]
Edit
As an aside, since type names are metaclasses in Python, naming your variables by the type name is a bad idea.
The reason is that can cause several issues further down in the code:
a = range(3) # [0,1,2]
type(a) # (type 'list')
isinstance(a, list) # True
Now, create a variable named list
list = range(3)
list # [0,1,2]
isinstance(list, list)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types
Not to mention, now you cant use the list() operator
c = list((1,2,3))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'list' object is not callable