Reputation: 574
I have a numerical list of list
a = [[1,2,3,4,5,6],
[7,8,9,10,11,12],
[13,14,15,16,17,18]]
and I want to replace every nth element with 0 to get something like this (n=3 in this case)
a = [[0,2,3,0,5,6],
[0,8,9,0,11,12],
[0,14,15,0,17,18]]
I am hoping to to it something like this
a = [[i, j if j %n == 0 else i] for i, j in a]
but I can't figure the arguments it needs.
Upvotes: 1
Views: 5076
Reputation: 123423
Although it would take more than one line of code, you could create a generalized solution by doing it like shown below, which would modify the list-of-lists inplace and therefore be more efficient than recreating the whole thing just to change a few values.
def replace_nth(list_of_lists, n, value):
for sublist in list_of_lists:
for i, v in enumerate(sublist):
if not i % n:
sublist[i] = value
a = [[1,2,3,4,5,6],
[7,8,9,10,11,12],
[13,14,15,16,17,18]]
replace_nth(a, 3, 0)
print(a) # -> [[0, 2, 3, 0, 5, 6], [0, 8, 9, 0, 11, 12], [0, 14, 15, 0, 17, 18]]
Upvotes: 1
Reputation: 1633
Solution
a = [[0 if index==0 else j for index, j in enumerate(i)] for i in a]
>>> a = [[1,2,3,4,5,6], [7,8,9,10,11,12], [13,14,15,16,17,18]]
>>> a = [[0 if index==0 else j for index, j in enumerate(i)] for i in a]
>>> a
[[0, 2, 3, 4, 5, 6], [0, 8, 9, 10, 11, 12], [0, 14, 15, 16, 17, 18]]
In Python 3.8 you will introduce Assignment Expressions.
It is a new symbol := that allows assignment in (among other things) comprehensions.
Upvotes: 0
Reputation: 19322
ggorlen has the right approach, but just to elaborate for your understanding and others who wanna learn list comprehensions..
First you need to iterate over each of the items in the list -
[item for item in l]
[[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, 18]]
Next, you have a condition that is applied on the index (position must be 3), but you need to modify the element itself as well. So you need to iterate over both the index and the element together.
[[(i,n) for i,n in enumerate(item)] for item in l]
[[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)],
[(0, 7), (1, 8), (2, 9), (3, 10), (4, 11), (5, 12)],
[(0, 13), (1, 14), (2, 15), (3, 16), (4, 17), (5, 18)]]
Each tuple is (index, element). Lastly you need your condition. There are multiple ways for using if conditions in a list comprehension, but for your case you need to check the index in the (index, element) tuple and see if it returns a remainder when divided by 3. If yes, then return the element else return 0.
[[n if i%3 else 0 for i,n in enumerate(item)] for item in l]
[[0, 2, 3, 0, 5, 6], [0, 8, 9, 0, 11, 12], [0, 14, 15, 0, 17, 18]]
Hope this explanation helps you with future problems like this.
Cheers.
Upvotes: 1
Reputation: 12817
What about slicing the list and creating a new one with 0?
n=3;
a = [l[:n] + [0] + l[n+1:] for l in a]
Upvotes: 0
Reputation: 56875
You can use a ternary if
-else
inside the inner list comprehension and enumerate
to access the index with each element as tuples:
n = 3
result = [[x if i % n else 0 for i, x in enumerate(y)] for y in a]
Applied to your example list,
>>> a = [[1,2,3,4,5,6],[7,8,9,10,11,12],[13,14,15,16,17,18]]
>>> n = 3
>>> [[x if i % n else 0 for i, x in enumerate(y)] for y in a]
[[0, 2, 3, 0, 5, 6], [0, 8, 9, 0, 11, 12], [0, 14, 15, 0, 17, 18]]
Upvotes: 5
Reputation: 2029
Try this code.
a = [[1,2,3,4,5,6],
[7,8,9,10,11,12],
[13,14,15,16,17,18]]
n=3
for out in range(0,len(a)):
for i in range(0,len(a[out])):
if i == n:
a[out][i] = 0
print(a)
Upvotes: 0