Search code examples
pythonlistdictionarycounting

How to track element count and last index in their original list?


I need a very efficient way to iterate over a list and put its element as a dictionary keys and their count and last position as values in a list of size two.

For example, the list [1,1,1,2] must produce the dictionary {1:[3,2], 2:[1,3]}.

I expected this code to work:

myList = [1,1,1,2,2,2,3,4,5,5,6,7]
myDict = dict.fromkeys(myList, [0,0])
for i, e in enumerate(myList):
    print(i, e)
    myDict[e][0] += 1
    myDict[e][1] = i
    
print(myDict)

But its output is

{1: [12, 11], 2: [12, 11], 3: [12, 11], 4: [12, 11], 5: [12, 11], 6: [12, 11], 7: [12, 11]}

instead of

{1: [3, 2], 2: [3, 5], 3: [1, 6], 4: [1, 7], 5: [2, 9], 6: [1, 10], 7: [1, 11]}

I did not expect this, because I considered iteration variables (i,e) as "usual" variables and therefore I expected a "copy" of them to be assigned, not a reference like it would happen in case of lists.

How to solve this problem?


Solution

  • The issue comes from your dict.fromkeys(...) call. It is assigning the same object [0,0] to all keys, not a copy of this object.

    The solution is to initialize your output dictionary as an empty dictionary. Then in your loop, first check if the key is already in the dictionary or not. If not then initialize the new key with [0,0], else perform the increment and index update as you already do in your code.