0

I have one list like this:

>>> a = ['1G', '1G', '1G', '1G', '10G', '10G', '10G', '10G', '25G', '25G', '25G', '25G']

Here are the indexes of the elements which I want to change in list a:

>>> ind = [4, 8]

I want to change 4th and 8th index elements with following:

>>> mode = ['40G', '100G']

I tried this:

>>> for i, m in zip(ind, mode):
...  a[i] = m

With this, I am able to update 4th and 8th index elements in list a:

>>> a
['1G', '1G', '1G', '1G', '40G', '10G', '10G', '10G', '100G', '25G', '25G', '25G']

I want to delete 3 elements after 4th index (i.e. 5, 6, 7) and 3 elements after 8th index (i.e. 9, 10, 11) from a, I am not able to delete them in one shot. Can someone please help me with this problem?

>>> for i, m in zip(ind, mode):
...  del a[i+1:i+4]
...

But after this I loose index

cs95
  • 379,657
  • 97
  • 704
  • 746
  • the problem is that after deleting one element, the indices change. So you either have to do it from the back to the end or compensate for the change as you delete. – Ma0 Aug 31 '17 at 07:20
  • How did you try to delete those list items, and what happened? – PM 2Ring Aug 31 '17 at 07:20

4 Answers4

1

As Ev. Kounis mentioned, when you delete the elements, the indices shift one place left, so you'll have to account for that. Do that first.

idx_to_delete = [5, 6, 7, 9, 10, 11]
for i, x in enumerate(idx_to_delete):
    idx_to_delete[i] -= i

print(idx_to_delete)
[5, 5, 5, 6, 6, 6]

Now, you can move onto deletion.

a = ['1G', '1G', '1G', '1G', '40G', '10G', '10G', '10G', '100G', '25G', '25G', '25G']
for i in idx_to_delete:
    del a[i]

print(a) 
['1G', '1G', '1G', '1G', '40G', '100G']
cs95
  • 379,657
  • 97
  • 704
  • 746
0

The trouble is indices of the elements will change once you have deleted an item. But that problem can be skirted off. Once you have the list a, store the indices that you want to delete in a list and sort it in reverse order

a = ['1G', '1G', '1G', '1G', '40G', '10G', '10G', '10G', '100G', '25G', '25G', '25G']
del_ind = [5,6,7,9,10,11]
del_ind.sort()
del_ind = del_ind[::-1]

Once the sorting is done you can go ahead and delete the items. The reason this works is because when you delete the last item, the indices of all the other items stay the same. So now you dont have to worry about changing indices -

for i in del_ind:
    del a[i]
print(a)
# ['1G', '1G', '1G', '1G', '40G', '100G']
Clock Slave
  • 7,627
  • 15
  • 68
  • 109
0

I suggest you to use the slice functionalty:

a = [  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ]
index = [4, 8]

a = a[:index[0]] + a[index[0]+3:index[1]] + a[index[1]+3 :]

print(a)

# result: [1, 2, 3, 4, 8, 12, 13, 14, 15]

This works because the slice do not change the list but return a new copy of the slice selected of it. For more information about slicing you should take a look at this StackOverflow answer.

rakwaht
  • 3,666
  • 3
  • 28
  • 45
0

Here are the two solutions I mentioned in the comments:

With compensation:

a = ['1G', '1G', '1G', '1G', '40G', '10G', '10G', '10G', '100G', '25G', '25G', '25G']
ind = [4, 8]
to_delete = [i for j in [list(range(x+1, x+4)) for x in ind] for i in j]  
# can the compensation be incorporated in the list-comprehension? hmm..
counter = 0
for i in to_delete:
    a.pop(i - counter)
    counter += 1
print(a)  # ['1G', '1G', '1G', '1G', '40G', '100G']

Accessing the list from behind:

a = ['1G', '1G', '1G', '1G', '40G', '10G', '10G', '10G', '100G', '25G', '25G', '25G']
ind = [4, 8]
to_delete = sorted([i for j in [list(range(x+1, x+4)) for x in ind] for i in j], reverse=True)
for i in to_delete:
    a.pop(i)
print(a)  # ['1G', '1G', '1G', '1G', '40G', '100G']
Ma0
  • 15,057
  • 4
  • 35
  • 65
  • Thanks much @ Ev. Kounis! I liked the first solution, crisp and clear. –  Aug 31 '17 at 07:40