0

i want to get know how many pair of numbers are present in the list

ar=[10 ,20 ,20 ,10 ,10 ,30 ,50 ,10 ,20]

this is the list

and i want to get the output 3. because there are 2 pair of 10 and one pair of 20

and this is my code

for i in ar:
    print(i)
    if ar.count(i)%2:
        ar.remove(i)
        print('removing ..' ,i)
print('numbers of pairs is : ',len(ar)//2)
print('after removing the odds ',ar)

output

10
20
removing .. 20
10
10
30
removing .. 30
10
20
numbers of pairs is :  3
after removing the odds  [10, 20, 10, 10, 50, 10, 20]

why this code is not removing the 50 from the list ?

i'm using jupyter notebook and i run this code onces again and the output is:

10
20
10
10
50
removing .. 50
20
numbers of pairs is :  3
after removing the odds  [10, 20, 10, 10, 10, 20]

the for loop is not reading the 50 from the array at the first run. that's why this code is not working, and my question is , why ,for loop is not reading this number ?

SOORYADEV
  • 39
  • 1
  • 7
  • Do not remove from list while iterating on it, never – azro Jan 04 '21 at 17:58
  • The first line may be written `for i in reversed(ar):` and the code will delete starting at the right moving towards the left. – Chris Charley Jan 04 '21 at 18:05
  • Use a copy of the `ar` list to manipulate, and only use the `ar` list to iterator: ```ar = [10, 20, 20, 10, 10, 30, 50, 10, 20] ar2 = ar.copy() for i in ar: print(i) if ar2.count(i) % 2: ar2.remove(i) print('removing ..', i) print('numbers of pairs is:', len(ar2) // 2) print('after removing the odds', ar2)``` Output: ```10 20 removing .. 20 20 10 10 30 removing .. 30 50 removing .. 50 10 20 numbers of pairs is: 3 after removing the odds [10, 20, 10, 10, 10, 20]``` – Red Jan 04 '21 at 18:06

1 Answers1

1

Never remove from list while iteraring on it, in any language I'd say.

An easy solution is to use a list comprehension and keep the one that matters

ar = [elt for elt in ar if not ar.count(elt) % 2]

Imagine with [1,2,4,5] you want to remove even numbers, you'll easy see that you'll miss element that are just after a one that you remove

forloop: cursor starts at 0    
cursor on box 0 -> value 1 -> condition NOK

forloop: cursor moves to 1
cursor on box 1 -> value 2 -> condition OK -> remove value 2

forloop: cursor moves to 2
cursor on box 2 -> value 5 -> condition NOK 
azro
  • 53,056
  • 7
  • 34
  • 70
  • Spot on. Nice. But the `list.count` is quite expensive, -The time complexity of the count(value) method is O(n) for a list with n elements. So the suggestion works well for a small list, if the list is huge, maybe consider - `collections.Counter` the filter out? – Daniel Hao Jan 04 '21 at 20:42