-3

I have the following script. I ask the user for categories and every category can be sorted in a couple of different ways also given by the user. The output should thus be something like:

{'a': ['b', 'c'], 'd': ['e', 'f']}

But it comes:

{'a': ['b', 'c', 'e', 'f'], 'd': ['b', 'c', 'e', 'f']}

I think that it's because i refer to the same list in each category. I don't really know how to make it dynamic and clearing the list afterwards doesn't seem to give to proper result either.

Can someone point me in the right direction? Thanks in advance

def user_settings():
    settings = {}
    sorteer = []
    while True:

        categorie = input('wat wordt de naam van de categorie: \n')
        if categorie == 'q':
            break
        while True:
            sorteren = input('waar wil je op sorteren: \n')
            if sorteren == 'q':
                break
            sorteer.append(sorteren)
            settings[categorie] = sorteer
    print(settings)
Myron
  • 11
  • 1
  • 2
  • 1
    When providing an example of incorrect output, you should _always_ include the input one can use to reproduce the output. – ndmeiri Feb 18 '18 at 19:29
  • Please provide more details as your query seems incomplete to me. – anurag0510 Feb 18 '18 at 19:33
  • Thank you for your reply. The first question asks about the key in the dictionary, which would be 'a' in this case. after that the script will ask for the values for that key. Which in this case will be 'b' and 'c' After that I press q to go to the next key which will be 'd' and after that the corresponding values 'e' and 'f'. After that we press 'q' two times to end the script and get the output. – Myron Feb 18 '18 at 19:38

2 Answers2

0

In python lists are mutable and you are using sorteer list against keys in settings dict. Every time you make a change in list(adding or removing element) it reflects against each key as you are using the same list. For detailed understanding refer: Does Python have an immutable list?

You can change your program to:

   def user_settings():
    settings = {}
    while True:
        categorie = input('Enter category: \n')
        if categorie == 'q':
            break
        while True:
            sorteren = input('enter range: \n')
            if sorteren == 'q':
                break
            if categorie in settings: #for python2.X use if settings.has_key(categorie)
                settings[categorie].append(sorteren)
            else:
                settings[categorie]=[sorteren]
    print(settings)

user_settings()

Output: {'a': ['b', 'c'], 'd': ['e', 'f']}

Priya Jain
  • 795
  • 5
  • 15
  • 1
    Dear Prya Jain Thank you for your reply. i get following error: AttributeError: 'dict' object has no attribute 'has_key' If see that 'has_key' is not longer used in python 3x and instead you should use in, but if I try to change it i get the following TypeError: TypeError: 'in ' requires string as left operand, not dict – Myron Feb 18 '18 at 20:02
  • Edited the answer to support python3. – Priya Jain Feb 19 '18 at 07:05
0

tl;dr move sorteer = [] one line down, so that it's inside the while-loop

def user_settings():
    settings = {}
    while True:
        sorteer = []
        categorie = input('wat wordt de naam van de categorie: \n')
        if categorie == 'q':
            break
        while True:
            sorteren = input('waar wil je op sorteren: \n')
            if sorteren == 'q':
                break
            sorteer.append(sorteren)
            settings[categorie] = sorteer
    print(settings)

Explanation: sorteer = [] creates a new list. Unfortunately, you only do that once. It means you have just 1 list. Not only all the values of your dictionary have the same elements, but they are exactly the same object:

>>> sorteer['a'] == sorteer['d']
True
>>> sorteer['a'] is sorteer['d']
True

sorteer.append(sorteren) doesn't create a copy of the list. So all the keys are mapped to the only list you have, the one you created at the beginning.

The easiest way to fix your code is to create a new list every time you start a new loop of while.

kszl
  • 1,203
  • 1
  • 11
  • 18
  • Thank you very much for your help, this solution also worked. I thought I tried this, but I put it in the wrong while loop, which does not give the right result. Which in hindsight makes sense! – Myron Feb 19 '18 at 07:28