0

I am trying to write a function in python which counts the occurrences of letters in the text shifted by x characters. The function works and saves the counted results in the dictionary, but when I want to save this dictionary to another one, the values already saved in it are written by the new dictionary that I add.

Here's my code:

def calcLetter(message):
    messageWithoutSpace = message.replace(" ", "")
    shift = 6
    alphabet = list(string.ascii_lowercase)
    position = {}
    tempList = {}

    for pos in range(0, 6):
        for letter in alphabet:
            tempList[letter] = {}
            textLenght = len(messageWithoutSpace)
            tempCount = 0
            letterIndex = 0
            while textLenght > 0:
                if len(messageWithoutSpace) - pos > letterIndex:
                    if messageWithoutSpace[pos + letterIndex] == letter:
                        tempCount += 1
                letterIndex = letterIndex + shift
                textLenght = textLenght - shift
            tempList[letter] = tempCount

        print("Start position:", pos)
        print(tempList)
        position[pos] = tempList

    print(position)

When I check it for each index, the letters are well counted, but only the last calculations are saved in the final dictionary.

Result:

Start position: 0
{'a': 16, 'b': 1, 'c': 3, 'd': 1, 'e': 10, 'f': 2, 'g': 5, 'h': 5, 'i': 0, 'j': 11, 'k': 7, 'l': 4, 'm': 0, 'n': 9, 'o': 8, 'p': 7, 'q': 3, 'r': 0, 's': 4, 't': 0, 'u': 6, 'v': 7, 'w': 5, 'x': 2, 'y': 5, 'z': 3}
Start position: 1
{'a': 1, 'b': 6, 'c': 1, 'd': 0, 'e': 7, 'f': 20, 'g': 3, 'h': 0, 'i': 7, 'j': 4, 'k': 8, 'l': 2, 'm': 0, 'n': 4, 'o': 0, 'p': 6, 'q': 7, 'r': 10, 's': 3, 't': 5, 'u': 4, 'v': 17, 'w': 1, 'x': 0, 'y': 3, 'z': 4}
Start position: 2
{'a': 4, 'b': 6, 'c': 12, 'd': 6, 'e': 0, 'f': 9, 'g': 4, 'h': 3, 'i': 2, 'j': 0, 'k': 2, 'l': 0, 'm': 4, 'n': 9, 'o': 12, 'p': 2, 'q': 2, 'r': 8, 's': 6, 't': 0, 'u': 5, 'v': 1, 'w': 11, 'x': 2, 'y': 7, 'z': 6}
Start position: 3
{'a': 13, 'b': 6, 'c': 2, 'd': 5, 'e': 2, 'f': 11, 'g': 0, 'h': 2, 'i': 0, 'j': 11, 'k': 1, 'l': 1, 'm': 3, 'n': 2, 'o': 7, 'p': 12, 'q': 2, 'r': 0, 's': 8, 't': 11, 'u': 5, 'v': 3, 'w': 0, 'x': 8, 'y': 0, 'z': 8}
Start position: 4
{'a': 7, 'b': 0, 'c': 6, 'd': 8, 'e': 14, 'f': 0, 'g': 4, 'h': 3, 'i': 9, 'j': 2, 'k': 3, 'l': 1, 'm': 10, 'n': 0, 'o': 5, 'p': 4, 'q': 10, 'r': 7, 's': 9, 't': 0, 'u': 0, 'v': 6, 'w': 6, 'x': 9, 'y': 0, 'z': 0}
Start position: 5
{'a': 2, 'b': 0, 'c': 5, 'd': 4, 'e': 5, 'f': 5, 'g': 0, 'h': 4, 'i': 0, 'j': 7, 'k': 5, 'l': 9, 'm': 0, 'n': 7, 'o': 6, 'p': 16, 'q': 0, 'r': 2, 's': 3, 't': 14, 'u': 2, 'v': 3, 'w': 4, 'x': 1, 'y': 10, 'z': 9}
{0: {'a': 2, 'b': 0, 'c': 5, 'd': 4, 'e': 5, 'f': 5, 'g': 0, 'h': 4, 'i': 0, 'j': 7, 'k': 5, 'l': 9, 'm': 0, 'n': 7, 'o': 6, 'p': 16, 'q': 0, 'r': 2, 's': 3, 't': 14, 'u': 2, 'v': 3, 'w': 4, 'x': 1, 'y': 10, 'z': 9}, 1: {'a': 2, 'b': 0, 'c': 5, 'd': 4, 'e': 5, 'f': 5, 'g': 0, 'h': 4, 'i': 0, 'j': 7, 'k': 5, 'l': 9, 'm': 0, 'n': 7, 'o': 6, 'p': 16, 'q': 0, 'r': 2, 's': 3, 't': 14, 'u': 2, 'v': 3, 'w': 4, 'x': 1, 'y': 10, 'z': 9}, 2: {'a': 2, 'b': 0, 'c': 5, 'd': 4, 'e': 5, 'f': 5, 'g': 0, 'h': 4, 'i': 0, 'j': 7, 'k': 5, 'l': 9, 'm': 0, 'n': 7, 'o': 6, 'p': 16, 'q': 0, 'r': 2, 's': 3, 't': 14, 'u': 2, 'v': 3, 'w': 4, 'x': 1, 'y': 10, 'z': 9}, 3: {'a': 2, 'b': 0, 'c': 5, 'd': 4, 'e': 5, 'f': 5, 'g': 0, 'h': 4, 'i': 0, 'j': 7, 'k': 5, 'l': 9, 'm': 0, 'n': 7, 'o': 6, 'p': 16, 'q': 0, 'r': 2, 's': 3, 't': 14, 'u': 2, 'v': 3, 'w': 4, 'x': 1, 'y': 10, 'z': 9}, 4: {'a': 2, 'b': 0, 'c': 5, 'd': 4, 'e': 5, 'f': 5, 'g': 0, 'h': 4, 'i': 0, 'j': 7, 'k': 5, 'l': 9, 'm': 0, 'n': 7, 'o': 6, 'p': 16, 'q': 0, 'r': 2, 's': 3, 't': 14, 'u': 2, 'v': 3, 'w': 4, 'x': 1, 'y': 10, 'z': 9}, 5: {'a': 2, 'b': 0, 'c': 5, 'd': 4, 'e': 5, 'f': 5, 'g': 0, 'h': 4, 'i': 0, 'j': 7, 'k': 5, 'l': 9, 'm': 0, 'n': 7, 'o': 6, 'p': 16, 'q': 0, 'r': 2, 's': 3, 't': 14, 'u': 2, 'v': 3, 'w': 4, 'x': 1, 'y': 10, 'z': 9}}
  • By doing `position[pos] = tempList` you keep adding **the same** dict. Maybe you need to move the `tempList = {}` to be inside the `for pos` loop – Tomerikoo Oct 22 '20 at 09:49
  • Does this answer your question? [List of lists changes reflected across sublists unexpectedly](https://stackoverflow.com/questions/240178/list-of-lists-changes-reflected-across-sublists-unexpectedly) – Tomerikoo Oct 22 '20 at 09:50
  • 2
    @Tomerikoo move tempList = {} inside the for pos loop solved the problem, thank you – Jakub Słowiński Oct 22 '20 at 10:03

2 Answers2

0

you need to copy tempList

>>> d = {1: '1', 2: '2'}
>>> l = [d, d.copy()]
>>> d[1] = '3'
>>> l
[{1: '3', 2: '2'}, {1: '1', 2: '2'}]
MarcMush
  • 1,439
  • 6
  • 13
0

This happens because python dictionaries are mutable. You are not making a copy of the dictionary by adding it to your list, you are just referencing the object (and later making changes). Because your list contains repeated references to the same object, the content of all list entries changes.

Try importing copy and changing position[pos] = tempList to position[pos] = copy.copy(tempList).

Tim
  • 331
  • 1
  • 7
  • For that matter instead of importing `copy` you can just use the `dict` constructor... `position[pso] = dict(tempList)` – Tomerikoo Oct 22 '20 at 10:12