1

I'm trying to create a dictionary of lists for an inventory. Example I add 'fruits', 'vegetables', 'drinks' as keys of a dictionary then I create a list for each of them. Once created, I add two items (e.g. 'apple','manggo') for each list so I can print them out like this:

fruits is list
items in fruits are apple, manggo
veggies is list
items in veggies are cabbage, cucumber
drinks is list
items in drinks are iced tea, juice

However I am unable to identify the items of newly created list and I only get this:

fruits is list
items in fruits are fruits

My code:

class Inventory:


    def __init__(self):

        self.dict_inv = dict()
        self.count_inv = int(input("Enter the number of inventories: "))


        for count in range(self.count_inv):

            self.name_inv = str(input("Enter Inventory #%d: " % (count+1)))
            self.dict_inv[self.name_inv] = count
            self.name_inv = list()

            sample_add = str(input("Add item here: "))
            self.name_inv.append(sample_add)

            sample_add2 = str(input("Add another item here: "))
            self.name_inv.append(sample_add2)


        for keys in self.dict_inv.keys():
            if type([keys]) is list:
                print("%s is list" % keys)
                print("items in %s are %s" % (keys,str(keys)))


Inventory()  
Geni-sama
  • 307
  • 5
  • 15

2 Answers2

1

You should test your actual lists, not a list of the keys()-view you get from the dict :

class Inventory:


    def __init__(self):

        self.dict_inv = dict()
        self.count_inv = int(input("Enter the number of inventories: "))


        for count in range(self.count_inv):

            name_inv = str(input("Enter Inventory #%d: " % (count+1)))

            # simply add the list here 
            self.dict_inv[name_inv] = []

            sample_add = str(input("Add item here: "))
            # simply add empty list for that key directly, no need to store count here 
            self.dict_inv[name_inv].append(sample_add)

            sample_add2 = str(input("Add another item here: "))
            # simply append to the list here 
            self.dict_inv[name_inv].append(sample_add2)

        for key in self.dict_inv.keys():

            # dont create a list of one single key, use the dicts value instead
            if type(self.dict_inv[key]) is list:
                print("{} is list".format(key) )
                print("items in {} are {}".format(key, self.dict_inv[key]))


Inventory()  

Output for input of 2,egg,1,2,tomato,3,4:

egg is list
items in egg are ['1', '2']
tomato is list
items in tomato are ['3', '4'] 

Change the output by using:

print("items in {} are {}".format(key, ', '.join(self.dict_inv[key])))

to get closer to your desired output:

egg is list
items in egg are 1, 2
tomato is list
items in tomato are 3, 4

HTH

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
  • Can i ask a question? why did you change 'self.name_inv' to simply 'name_inv'? – Geni-sama Oct 04 '18 at 15:15
  • @Geni-sama you can change it back. I do not see the point to store all items in a dict.value as list AND as member variable on the class itself - its duplicate data. – Patrick Artner Oct 04 '18 at 15:17
  • @Geni-sama It also only ever stores the _last_ inputted key , so I did not see the sense behind it :) to store tomato as member but not egg ... – Patrick Artner Oct 04 '18 at 15:18
  • Another question. When i use '*self.dict_inv[key]' it only shows the first item (in my case it is 'apple) but when i remove the asterisk and use 'self.dict_inv[key], it displays the whole list. Why is that? – Geni-sama Oct 04 '18 at 15:21
  • @Geni-sama the asterix before a list decomposes it. `print ( [ 1, 2 , 3, 4] )` with an asterix becomes the same output as `print( 1, 2 , 3 , 4 )` --> the list is decomposed into its elemenst. `print(*self.dict_inv[key])` should show all elements of the list stored at [key]. Its allso called "unpacking" f.e. https://stackoverflow.com/questions/6319612/python-decompose-a-list – Patrick Artner Oct 04 '18 at 19:20
0

In your last line you're actually printing the same thing twice there. First you're printing the key then you're converting it to a string and printing it.

Change your last line to the following:

for key in self.dict_inv.keys():
    if type(self.dict_inv[key]) is list:
        print("%s is list" % key)
        print("items in %s are %s" % (key, *self.dict_inv[key])))

Here self.dict_inv[key] is accessing the list and the * in front is exposing it each item inside the list instead of just the list itself!

Side note: I think it's preferred in python 3+ now to use .format() rather than %, but that's beside the point.

Capn Jack
  • 1,201
  • 11
  • 28
  • When i used the '*self.dict_inv[key]' it only displayed the first item and not the second one. – Geni-sama Oct 04 '18 at 15:23
  • Then you likely only have one item in that list. Check your code, you're making a for loop and near the end you make a list with two input items but then you do nothing with it. If you want it in your dict then you should use `self.dict_inv[count] = self.name_inv` – Capn Jack Oct 04 '18 at 15:26
  • Thank you for the reference. Strange that all second items are not displaying after typing all of them in. – Geni-sama Oct 04 '18 at 15:30
  • @Geni-sama Yup exactly, check my edit to my comment above. They don't appear because you don't do anything with the list after you've made it. So it's just lost after that iteration ends. – Capn Jack Oct 04 '18 at 15:31