2

I have a list of tuples (num, id):

l = [(1000, 1), (2000, 2), (5000, 3)]

The second element of each tuple contains the identifier. Say that I want to remove the tuple with the id of 2, how do I do that?

I.e. I want the new list to be: l = [(1000,1), (5000, 3)]

I have tried l.remove(2) but it won't work.

Georgy
  • 12,464
  • 7
  • 65
  • 73

6 Answers6

9

You can use a list comprehension with a filter to achieve this.

l = [(1000, 1), (2000, 2), (5000, 3)]
m = [(val, key) for (val, key) in l if key != 2]
Curtis Lusmore
  • 1,822
  • 15
  • 16
  • It will work. But the question was to remove element from the list, but you are creating the new list – Moinuddin Quadri Sep 14 '16 at 00:51
  • @MoinuddinQuadri That is because an iterable such as a list should not be mutated whilst iterating over its contents, so the standard solution is to create a new list using a conditional list comprehension. http://stackoverflow.com/questions/1637807/modifying-list-while-iterating – Alexander Sep 14 '16 at 01:04
  • @Alexander I agree with you regarding the mutation part. But in this case, based on the requirement; ideal way I believe is to iterate over the copy of list and remove elements from the original list. – Moinuddin Quadri Sep 14 '16 at 01:07
  • @MoinuddinQuadri I strongly disagree. You could do a reassignment, e.g. `l = [tup for tup in l if tup[1] != 2]`. – Alexander Sep 14 '16 at 01:16
  • @Alexander: The answer to this will be based on one's perception. My view is based on the question asked `Remove a tuple from a list`. If this was not mentioned in the question, even I would be in favour of this answer. PS: I haven't down-voted (nor up-voted) this answer. – Moinuddin Quadri Sep 14 '16 at 01:21
3

Or using filter:

l = [(1000, 1), (2000, 2), (5000, 3)]
print(list(filter(lambda x: x[1] != 2, l)))

output:

[(1000, 1), (5000, 3)]
BPL
  • 9,632
  • 9
  • 59
  • 117
2

That's because the value 2 is not in the list. Instead, something like the below: form a list of the second elements in your tuples, then remove the element at that position.

del_pos = [x[1] for x in l].index(2)
l.pop(del_pos)

Note that this removes only the first such element. If your instance is not unique, then use one of the other solutions. I believe that this is faster, but handles only the single-appearance case.

Prune
  • 76,765
  • 14
  • 60
  • 81
0

You may do it with:

>>> l = [(1000, 1), (2000, 2), (5000, 3)]
>>> for i in list(l):
...     if i[1] == 2:
...         l.remove(i)

In case you want to remove only first occurence, add break below remove line

Moinuddin Quadri
  • 46,825
  • 13
  • 96
  • 126
  • This method is also much slower. ```from random import seed, randint seed(0) l = [(randint(1, 1000), randint(1, 5)) for _ in range(10000)] %time l2 = [tup for tup in l if tup[1] != 2] CPU times: user 8.38 ms, sys: 1.97 ms, total: 10.3 ms Wall time: 8.7 ms %%time for i in list(l): if i[1] == 2: l.remove(i) CPU times: user 285 ms, sys: 3.69 ms, total: 289 ms Wall time: 285 ms``` – Alexander Sep 14 '16 at 01:49
0

Simple list comprehension:

[x for x in l if x[1] != 2]
acw1668
  • 40,144
  • 5
  • 22
  • 34
0

One more possible solution

r = [(1000, 1), (2000, 2), (5000, 3)]
t = [i for i in r if i.count(2) == 0]
utks009
  • 573
  • 4
  • 14