0

I want to write a program in which as an input I take a list consisted of words which can contain punctuation marks. I built a dictionary where keys are elements of a given list and values are empty lists. My goal is to add to these lists (inside the this dictionary) the indexes of those chars from the words which are punctuation marks. The program works partially - the problem is, that it adds the proper index to the previous list, i. e. to the list for the previous key, not for the current one. If you analyze the code, you will see what I mean:

list1 = ['!,', 'Hey!']
dict_words = dict.fromkeys(list1, [])
print(list1)
print(dict_words)
print()
for word in list1:    
  counter_punc = 0
  print('"word": ', word, ' dict_words["word"]: ', dict_words[word])
  if word.isalpha():
    print("alpha word: ", word)
  else:
    print("non-alpha word: ", word)
    for letter in word:
      if letter.isalpha():
        print("alpha letter: ", letter) #, " non-alpha word: ", word)
      else:
        counter_punc += 1
        dict_words[word].append(word.index(letter))
        print("letter: ", letter, " index: ", word.index(letter))
        print('"word": ', word, ' dict_words["word"]: ', dict_words[word])
        # dict_words[word].append()
  print("word: ", word, " counter_punc: ", counter_punc)
  print()

Iterating through the items of this dictionary:

for k,v in dict_words.items():
  print(k,v)

we obtain that for both keys we have the same value, i. e. [0,1,3]. It is incorrect - it should be for the key !, the [0,1] value and for the key Hey!, the [3] value.

Could anyone point me where the bug is and how to fix it? I would be grateful for help.

  • 2
    Have a hunch only....maybe `dict_words = dict.fromkeys(list1, [])` is only creating one list object and putting it as the value for both keys. EDIT: verified by experiment that dict_words will have the exact same list object for each of its values after that. – Andrew Allaire Jan 20 '21 at 21:03
  • So, the problem is with creating the dictionary? I am not sure if I understand you correctly (I'm not a native). Having the dictionary created in this way, we always have the same value for each key, right? I thought it is only in that way at the beggining, but then I can modify, update values and they will stay different after. I wrote a simple code - not this one - to check if works and it works. I mean, we have a list and dictionary created by `.fromkeys()` method. Then in the for-loop for each key in the dict I added a value which was the lenght of that key, i. e. word. – CompactSpaces Jan 20 '21 at 21:29
  • https://nedbatchelder.com/text/names.html – wwii Jan 20 '21 at 21:44
  • dict_words['!,'] **is** dict_words['Hey!'] --> `True`. – wwii Jan 20 '21 at 21:49
  • @CompactSpaces What you want is for it to point to different list objects. Having them all point to the same list object means every append is just adding to the same list. As @wii points out by saying `dict['!,'] is dict_words['Hey!']`. In python the `is` operator tests if something is the same object. You want them to have empty lists, but different empty lists. You do NOT want them to have the very same empty list. – Andrew Allaire Jan 21 '21 at 00:15
  • Okay, thank you all for help. Now, I see what caused an error. I will read more about references in Python. Thank you all, once again. – CompactSpaces Jan 21 '21 at 11:24

1 Answers1

1

Something like this :

list1 = ['!,', 'Hey!']
dict_words = dict()
for word in list1:
    dict_words[word] = list()
    if not word.isalpha():
        for i, _char in enumerate(word):
            if not _char.isalpha():
                dict_words[word].append(i)
print(f'result : {dict_words}')

result : {'!,': [0, 1], 'Hey!': [3]}

pich
  • 36
  • 2
  • Thank you, I need some time to analyze this. I am not a pro and, for instance, I don't know what the underscore at the beginning of the name of a variable mean, but I will search it on the Internet. However, can you see where the bug in my code is and how to repair it? Nevertheless, thank you for spending your time and wanting to help me :) (edit) the underscore probably doesn't mean anything, but I came across with double underscore in python and it was probably important. – CompactSpaces Jan 20 '21 at 21:04
  • For @pich - good solution. But you don't have to use `_char` for this here, since it's not referring any `private` internal data. – Daniel Hao Jan 20 '21 at 21:14