0

i was just writing a code to count the frequencies of each element in a list and encountered an issue

please note that i know about the built-in count function but for this code im not allowed to use it

    a=[1,2,4,8,2,3,4,3,1,6]
    print(a)
    for i in a:
        count=0
        for j in a:
            if j==i:
                count+=1
                a.remove(i)
        print(i,' appears ',count,' times.')

Output

:

1  appears  2  times.                                                                                                   
4  appears  2  times.                                                                                                   
2  appears  2  times.                                                                                                   
6  appears  1  times.

The code just didnt count 3 and 8

  • 4
    [Don't change the list you are iterating over](https://unspecified.wordpress.com/2009/02/12/thou-shalt-not-modify-a-list-during-iteration/). Also, consider storing your result rather than just printing it, if you store the result as a dictionary where the keys are the unique values of your list and the values are the counts I think you'll find it will simplify things for you (hint: you won't need a nested loop anymore). – Dan Jan 10 '20 at 15:12
  • Don't `a.remove(i)` it creates a conflict and I think is not necessary. – Ivan Jan 10 '20 at 15:16
  • @harry_kris01 your solution really should not involve removing anything from the list nor a copy. I highly recommend you don't solve this using what you learn from wwii's link... – Dan Jan 10 '20 at 15:22
  • @Dan sir, thanks but .....the question specifies that a loop is to be used - thus i cant use the count function...... i'll find an other way where i'll take the loop range as indices and thus when equality satisfies , index decreases by 1... else increment by 1.... – harry_kris01 Jan 10 '20 at 15:24
  • @harry_kris01, I'm not suggesting you use `Counter` nor that you don't use loops. I'm saying that the correct solution uses a single loop and does not remove anything from your list. You do it with a dictionary. I highly recommend you try work out this solution. – Dan Jan 10 '20 at 15:49
  • @dan sir even if i use a dictionary ,isnt a nested loop required?how in 1 loop that too without using *count* ? kindly give me some clues.......(not code) can u give me your mail id ?(else take mine: explorerpython@gmail.com) – harry_kris01 Jan 10 '20 at 16:15
  • Loop once over the list. In an iteration you take the value from your list and try use it as the key in your dictionary. There are two cases, either it is already in your dictionary or it is not. Remember that you want the values of the dictionary to be the counts so all you have to do now is think about what actions to take in each of those two scenarios. – Dan Jan 10 '20 at 16:21
  • @dan sir please don't feel bad-- i still didnt get it...... – harry_kris01 Jan 10 '20 at 16:35
  • @dan sir i cant chat with u as my reputation is only 9 - is there a solution to that? – harry_kris01 Jan 10 '20 at 16:36
  • ok `counts = {}` `for item in a:` `try:` `counts[item] += 1` `except KeyError:` `counts[item] = 1` see if that makes sense to you :) – Dan Jan 10 '20 at 16:37
  • 1
    @dan sir , i got it- when the key doesnt exist i.e when KeyError occurs, the key-value pair is assigned with value 1 - after that whenever the elemnt is supposed to be existing in the dict , increment occurs- **am i right sir ?** – harry_kris01 Jan 10 '20 at 16:55
  • @dan sir Thanks so much for your code and helping out me.... – harry_kris01 Jan 10 '20 at 16:56
  • @harry_kris01 that's right. And this way your algorithm runs in O(n) instead of O(n^2). – Dan Jan 10 '20 at 17:18
  • @dan sir gotcha – harry_kris01 Jan 10 '20 at 18:01

1 Answers1

0

The problem is because the code in the first for loop changed the list a. For instance, in the first iteration for the first loop, a is [1, 2, 4, 8, 2, 3, 4, 3, 1, 6]. So in the first iteration, i is 1 which is the first element of a. However, later in the iteration, there is a.removed(i). Hence, a becomes [2, 4, 8, 2, 3, 4, 3, 1, 6]. In the second iteration, i starts with the second element of a which is 4. Hence, the code actually skiped 2. And it also skipped 8 and 3 for the same reason.

As a matter of fact, avoid changing the list a within the loop or do not loop through a.

a=[1,2,4,8,2,3,4,3,1,6]
print(a)
for i in set(a):
    count=0
    for j in a:
        if j==i:
            count+=1
            a.remove(i)
    print(i,' appears ',count,' times.')
JCHU
  • 33
  • 5