Python Forum
Adding to the dictionary inside the for-loop - weird behaviour
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Adding to the dictionary inside the for-loop - weird behaviour
#1
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 value
[0,1]
and for the key
'Hey!'
the value
[3]


Could anyone point me where the bug is and how to fix it?
I would be grateful for help.
Reply
#2
It's the line :

dict_words = dict.fromkeys(list1, [])
That's causing the trouble. I'm not sure how you would use the method fromkeys differently in order to correct the problem but if you replace that line with :
dict_words = {'!,': [], 'Hey!': []}
then your code will produce the expected results.
InputOutput007 likes this post
Reply
#3
here's what I get:
>>> list1 = ['!,', 'Hey!']
>>> dict_words = dict.fromkeys(list1, [])
>>> for k, v in dict_words.items():
...     print(f"k: {k}, v: {v}")
... 
k: !,, v: []
k: Hey!, v: []
>>>
InputOutput007 likes this post
Reply
#4
fromdict takes a list of keys and a value and assigns that value to all keys. If you send a list as value, all keys share the same list. When you print the dictionary you can see that all keys have an empty list but you can't see that it is the same list and that the keys share it. The only way get around the problem is as @BashBedlam indicates.
InputOutput007 likes this post
Reply
#5
spam = ['foo', 'bar']
eggs = dict.fromkeys(spam, [])
print(eggs)
print([id(item) for item in eggs.values()])
Output:
{'foo': [], 'bar': []} [140175770726664, 140175770726664]
lists are mutable and as you can see all keys refer to same object (same id). Update is reflected in all of them.

you can do eggs = {key:[] for key in spam}
alternatively, you can use collections.defaultdict with default value being list
Serafim and InputOutput007 like this post
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#6
Hey guys! Thank you all for the explanation and spending your time helping me.
Thank you: @BashBedlam, @Larz60+, @Serafim, @buran :)
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Variable definitions inside loop / could be better? gugarciap 2 373 Jan-09-2024, 11:11 PM
Last Post: deanhystad
  How to create a variable only for use inside the scope of a while loop? Radical 10 1,523 Nov-07-2023, 09:49 AM
Last Post: buran
  logger behaviour setdetnet 1 853 Apr-15-2023, 05:20 AM
Last Post: Gribouillis
  can someone explain this __del__ behaviour? rjdegraff42 1 692 Apr-12-2023, 03:25 PM
Last Post: deanhystad
  Asyncio weird behaviour vugz 2 1,189 Apr-09-2023, 01:48 AM
Last Post: vugz
  Weird behaviour using if statement in python 3.10.8 mikepy 23 3,422 Jan-18-2023, 04:51 PM
Last Post: mikepy
  Help adding a loop inside a loop Extra 31 4,332 Oct-23-2022, 12:16 AM
Last Post: Extra
  Generator behaviour bla123bla 2 1,072 Jul-26-2022, 07:30 PM
Last Post: bla123bla
  For Loop and Use of Brackets to Modify Dictionary in Tic-Tac-Toe Game new_coder_231013 7 2,167 Dec-28-2021, 11:32 AM
Last Post: new_coder_231013
  Inconsistent behaviour in output - web scraping Steve 6 2,445 Sep-20-2021, 01:54 AM
Last Post: Larz60+

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020