Python: some list accessing issue [duplicate] - python

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]

Related

Creating new indexin in list python

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

Why list indexing [-4:0] not working while [0:4] works?

If negative list indexing is starting from the end the list and let's say we have:
l = [1,2,3,4,5]
and l[0:3] and l[:3] returns same values while l[-3:0] returns an empty list and l[-3:] returns [3,4,5]
What is the logic behind not allowing list[-x:0] to return the list?
l[-3:0] tries to slice from 3 from behind towards 0 - that is the same as l[2:0] .. that slices nothing because the first value > second value.
l[-3:] can be read as l[-3:len(l)] - so l[2:5] which returns the slice.
You would need l[-3:0:-1] for that to work - but thats mind boggling slicing which I try to avoid. ( print( [1,2,3,4,5][-3:0:-1] --> [3, 2] ) because it also reverses the slice "orientation" to backwards instead of forwards
l[-3:] slices from 3 from behind till the end.
The full notation of slice in Python is the following:
s[start:end:step]
That being said it provides useful defaults for the values, as per the documentation:
Slice indices have useful defaults; an omitted first index defaults to
zero, an omitted second index defaults to the size of the string being
sliced.
So when you do something like:
s[1:]
under the hood this is done:
s[1:len(s)]
Note that in both cases step defaults to 1. In most languages when you want to access the last element of a list for example you do something like:
s[len(s) - 1]
Python negative indexing is a sort of syntactic sugar on that notation so :
l[-1] = l[len(l) - 1]
l[-2] = l[len(l) - 2]
...
Then when you do:
l[-3:]
this is done:
l[len(l)-3:len(l)]
So, instead of 0 you should use len(l) as the last index:
l = [1, 2, 3, 4, 5]
print(l[-3:len(l)])
Output
[3, 4, 5]
Note that l[-3:0] returns the empty list because len(l) - 3 > 0, i.e. the first index is greater than the second and step is 1.
Further
Understanding Python's slice notation
Well 0 in front works, but at last... won't work, same with this:
>>> l=[1,2,3,4,5]
>>> l[2:0]
[]
>>>
because python is thinking zero at the end...
So that's virtually equivalent to:
>>> l=[1,2,3,4,5]
>>> l[:0]
[]
>>>
since of course there is nothing before first element, if there was, that thing wouldn't be first element, it would be second.
Negative indexes operate from the end of the list.
Say if you want to get the last 3 items, you could do:
# Reversing and restoring the order
my_list = [1,2,3,4,5,6]
print(reversed(reversed(my_list)[:3]))
# Subtracting from the size
size = len(my_list)
print(my_list[size-3:])
But instead you can type
my_list[-3:]
Which in words would state get me the slice of the list starting from the third item at the end of the list
So you have to be aware of what your asking for.
# Slice from the x'th element at the end till the end of the list
my_list[-x:]
# Slice from the x'th element at the end till the y'th element at the end of the list
my_list[-x:-y]
# Slice from the x'th element at the end till the y'th element from the start of the list.
# Only valid if len(my_list) - y < x and y > 0
my_list[-x:y]

Delete every element whose index satisfies condition; list assignment index out of range

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.

add item to list python

I would like to add an item to a list in python, I want to add the item at an index which is greater than the size of the list. This should cause the list to grow automatically.
For example with a list of 3 items, I would like to insert element at index 6. Is this possible in python without first having to reinitialize the list?
It seems Python will merely append to the list if you try to insert an item at index 6 in my example.
You could write a function which, given a list, an index, and an element, inserts the element in the list before the index if the index is in range (in which case this is equivalent to the built-in insert method) or extends the list by enough Nones to fill it out before tacking it on the end:
>>> def put(xs,i,e):
n = len(xs)
if i <= n:
xs.insert(i,e)
else:
xs.extend([None]*(i-n-1))
xs.append(e)
>>> xs = [1,2,3]
>>> put(xs,6,10)
>>> xs
[1, 2, 3, None, None, 10]
>>>

Array Indexing in Python

Beginner here, learning python, was wondering something.
This gives me the second element:
list = [1,2,3,4]
list.index(2)
2
But when i tried this:
list = [0] * 5
list[2] = [1,2,3,4]
list.index[4]
I get an error. Is there some way to pull the index of an element from an array, no matter what list it's placed into? I know it's possible with dictionaries:
info = {first:1,second:2,third:3}
for i in info.values:
print i
1
2
3
Is there something like that for lists?
The index method does not do what you expect. To get an item at an index, you must use the [] syntax:
>>> my_list = ['foo', 'bar', 'baz']
>>> my_list[1] # indices are zero-based
'bar'
index is used to get an index from an item:
>>> my_list.index('baz')
2
If you're asking whether there's any way to get index to recurse into sub-lists, the answer is no, because it would have to return something that you could then pass into [], and [] never goes into sub-lists.
list is an inbuilt function don't use it as variable name it is against the protocol instead use lst.
To access a element from a list use [ ] with index number of that element
lst = [1,2,3,4]
lst[0]
1
one more example of same
lst = [1,2,3,4]
lst[3]
4
Use (:) semicolon to access elements in series first index number before semicolon is Included & Excluded after semicolon
lst[0:3]
[1, 2, 3]
If index number before semicolon is not specified then all the numbers is included till the start of the list with respect to index number after semicolon
lst[:2]
[1, 2]
If index number after semicolon is not specified then all the numbers is included till the end of the list with respect to index number before semicolon
lst[1:]
[2, 3, 4]
If we give one more semicolon the specifield number will be treated as steps
lst[0:4:2]
[1, 3]
This is used to find the specific index number of a element
lst.index(3)
2
This is one of my favourite the pop function it pulls out the element on the bases of index provided more over it also remove that element from the main list
lst.pop(1)
2
Now see the main list the element is removed..:)
lst
[1, 3, 4]
For extracting even numbers from a given list use this, here i am taking new example for better understanding
lst = [1,1,2,3,4,44,45,56]
import numpy as np
lst = np.array(lst)
lst = lst[lst%2==0]
list(lst)
[2, 4, 44, 56]
For extracting odd numbers from a given list use this (Note where i have assingn 1 rather than 0)
lst = [1,1,2,3,4,44,45,56]
import numpy as np
lst = np.array(lst)
lst = lst[lst%2==1]
list(lst)
[1, 1, 3, 45]
Happy Learning...:)
In your second example, your list is going to look like this:
[0, 0, [1, 2, 3, 4], 0, 0]
There's therefore no element 4 in the list.
This is because when you set list[2], you are changing the third element, not updating further elements in the list.
If you want to replace a range of values in the list, use slicing notation, for example list[2:] (for 'every element from the third to the last').
More generally, the .index method operates on identities. So the following will work, because you're asking python where the particular list object you inserted goes in the list:
lst = [0]*5
lst2 = [1,2,3,4]
lst[2] = lst2
lst.index(lst2) # 2
The answer to your question is no, but you have some other issues with your code.
First, do not use list as a variable name, because its also the name of the built-in function list.
Secondly, list.index[4] is different than list.index(4); both will give errors in your case, but they are two different operations.
If you want to pull the index of a particular element then index function will help. However, enumerate will do similar to the dictionary example,
>>> l=['first','second','third']
>>> for index,element in enumerate(l):
... print index,element
...
output
0 first
1 second
2 third

Categories

Resources