Removing items from a Python nested list

I am trying to remove items from a nested list in Python. I have a nested list as follows:

families = [[0, 1, 2],[0, 1, 2, 3],[0, 1, 2, 3, 4],[1, 2, 3, 4, 5],[2, 3, 4, 5, 6]] 

I want to delete entries in each sublist that are consistent with the subscriptor's indexed position in the main list. So, for example, I need to remove 0 from the first sublist, 1 from the second subscription, etc. I'm trying to use list comprehension, do it. This is what I tried:

 familiesNew = [ [ families[i][j] for j in families[i] if i !=j ] for i in range(len(families)) ] 

This works for range(len(families)) to 3, however outside of this I get IndexError: list index out of range . I do not know why. Can someone give me an idea on how to do this. Preferably single line (list comprehension).

Thanks.

+7
source share
4 answers

You understand almost everything. Just replace families[i][j] with j and it works:

 >>> [ [ j for j in families[i] if i !=j ] for i in range(len(families)) ] [[1, 2], [0, 2, 3], [0, 1, 3, 4], [1, 2, 4, 5], [2, 3, 5, 6]] 

Using the enumerate function, you can write it a little cleaner:

 >>> [[f for f in family if f != i] for i, family in enumerate(families)] [[1, 2], [0, 2, 3], [0, 1, 3, 4], [1, 2, 4, 5], [2, 3, 5, 6]] 

Or even using remove if you don't mind changing the original list:

 >>> for i, family in enumerate(families): family.remove(i) 
+9
source

Edited question by deleting my answer that solves the wrong problem. Additionally, an additional @Ashwini answer has been added:

For comparison:

 root# python -m timeit 'families = [[0, 1, 2],[0, 1, 2, 3],[0, 1, 2, 3, 4],[1, 2, 3, 4, 5],[2, 3, 4, 5, 6]]' '[x.remove(ind) for ind,x in enumerate(families) ]' 100000 loops, best of 3: 3.42 usec per loop root# python -m timeit -s 'families = [[0, 1, 2],[0, 1, 2, 3],[0, 1, 2, 3, 4],[1, 2, 3, 4, 5],[2, 3, 4, 5, 6]]' '[[f for f in family if f != i] for i, family in enumerate(families)]' 100000 loops, best of 3: 4.87 usec per loop root# python -m timeit -s 'families = [[0, 1, 2],[0, 1, 2, 3],[0, 1, 2, 3, 4],[1, 2, 3, 4, 5],[2, 3, 4, 5, 6]]' '[ filter(lambda x:x!=i,j) for i,j in enumerate(families) ]' 100000 loops, best of 3: 7.99 usec per loop 

These are microseconds, so I think that all you want to do is fine if you do not do it many times.

+5
source

Does it do what you want?

 familiesNew=[ filter(lambda x:x!=i,j) for i,j in enumerate(families) ] 

EDIT

Also note that the reason you failed is that in the third element of the external list ( [1, 2, 3, 4, 5] ) you are trying to get the fifth element in the for ( for j in families[i] == for j in [1,2,3,4,5] ), but the families [i] are 5, that is, the largest index is 4. Sorry if this explanation is a bit unclear ... maybe the following will help clean it:

 families = [[0, 1, 2],[0, 1, 2, 3],[0, 1, 2, 3, 4],[1, 2, 3, 4, 5],[2, 3, 4, 5, 6]] def f(i,j): print i,j,families[i] return families[i][j] #THIS DOES NOT WORK -- but it will tell you where it failed. familiesNew = [ [ f(i,j) for j in families[i] if i !=j ] for i in range(len(families)) ] 
+3
source

If you want to change the original list, try the following:

 >>>[x.remove(ind) for ind,x in enumerate(families) ] >>>families [[1, 2], [0, 2, 3], [0, 1, 3, 4], [1, 2, 4, 5], [2, 3, 5, 6]] 
+2
source

All Articles