#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    54
    Rep Power
    2

    Deleting from a Dictionary stored in a list


    Hi,

    I am trying to add or remove information from a dictionary based on user input. I'm having trouble deleting information from the dictionary which I placed within a list (Placed dictionary in a list so that I can add multiple entries to it).

    I tried del Student['name'] which doesn't seem to delete. Also I want to delete an entire information of a particular name that the user chooses to delete. Example not just the name 'Ashley' but the sex and last name too that is grouped to it.

    But based on the way I see it, when it is stored as follows:
    Code:
    {'Fname':'Ashley','age':'20','Lname':'cole'}
    the program is not going to know all these are the same person's information thus it will just delete 'Ashley' when the user chooses 'Ashley'. Or am I interpreting it wrong..

    Sorry if long winded. Trying to be clear. Tnks for advice. The codes as follows.

    Code:
    Students = [] 
    def printmenu(): 
        print 'MENU' 
        print '1. Add Student' 
        print '2. Remove Student' 
     
    def addStudent(): 
        addInput1 = raw_input('enter first name ') 
        addInput2 = raw_input('enter last name ') 
        addInput3 = raw_input('enter age ') 
    Student={'FName':addInput1,'LName':addInput2,'Age':addInput3}
    Students.append(Student) 
    return Students 
    
    def removeStudent(): 
        removeInput = raw_input('Please enter name of student to be removed: ') 
        del Students[removeInput] 
    
    userInput = '0' 
    while userInput != '-1': 
        printmenu() 
        userInput = raw_input('Please choose an option from the menu. Enter -1 to quit: ') 
        if userInput == '1': 
            addStudent() 
        elif userInput == '2': 
            removeStudent()  
        elif userInput == '-1': 
            print 'End of program' 
        else: 
            print 'Not a valid option. Try again.'
  2. #2
  3. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,841
    Rep Power
    480
    Delete an item from a list by its integral index.
    Code:
    import pdb
    import pprint
    
    def printmenu():
        print 'MENU'
        print 'a) Add Student'
        print 'b) Remove Student'
        print 'Entries other than a or b quit'
    
    def addStudent(Students):
        a = raw_input('enter first name ')
        b = raw_input('enter last name ')
        c = raw_input('enter age ')
        Students.append({'FName':a,'LName':b,'Age':c})
    
    def removeStudent(Students):
        # did you mean enter the first name or last name?  Check both.
        a = raw_input('Please enter name of student to be removed: ')
        for (i,student,) in enumerate(Students):
            if (student['FName'] == a) or (student['LName'] == a):
                if 'y' == raw_input('Remove %s?  '%str(student))[:1].lower():
                    del Students[i] # use index number to delete list item
    
    userInput = 'a'
    
    Students = []
    
    # you would really have used -1 as a string?????  Be serious.
    while userInput in set('ab'):
        printmenu()
        userInput = raw_input('Please choose an option from the menu.  ')
        if userInput == 'a':
            addStudent(Students)
        elif userInput == 'b':
            removeStudent(Students)
    
    # And now you'll discard your hard fought list???
    pprint.pprint(Students)
    
    print 'End of program'
    [code]Code tags[/code] are essential for python code and Makefiles!
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    54
    Rep Power
    2
    Hi thanks for reply. Regarding your question as to why I am deleting off a list which I just obtained - In total the user has 4 options. Add, delete, view a single name's data, or just all names. I just posted part of it (the deleting part) hoping not to overcrowd.

    I have now posted the full workout I have done which I re- adjusted with your help. Also kept the -1 as an integer. Was trying to keep -1 as a string in case I want to get user inputs as strings such as a,b,c instead of 1,2,3 which meant I had to do away it int(). Unless there is a better way around this which again am missing..

    Regarding your codes, I am not familiar with enumerate, import pdb and import pprint. From my understanding, enumerate helps to iterate through the list.

    For the imports, I removed them both and the codes still work fine. I read up that the pdb was a debugger though didn't really grasp the full detail. I believe you added it to showcase any issues in the program layout n syntax. As for pprint, from my understanding it is a better way of presenting the print layout. Do help advice if I am missing any details.

    A little off topic from deleting from dictionary. Regarding def viewStudent, I was trying to part copy the idea you gave for def removeStudent but it is not happening. Able to help hint me on what's wrong? Thanks so much.

    Code:
    Students = [] 
    def printmenu(): 
        print 'MENU' 
        print '1. Add Student' 
        print '2. Remove Student' 
        print '3. View Student' 
        print '4. View All Students' 
    
    def addStudent(): 
        addInput1 = raw_input('enter first name of student ')  
        addInput2 = raw_input('enter last name of student ')
        addInput3 = raw_input('enter the age of student ') 
        Student ={'FName':addInput1,'LName':addInput2,'Age':addInput3}  
        Students.append(Student) 
        return Students 
    
    def removeStudent(): 
        removeInput = raw_input('enter name of studend to R: ')
        for (i,Student,) in enumerate(Students): 
            if Student['First Name'] == removeInput: 
                del Students[i] 
    
    def viewStudent(): # wrong 
        viewInput = raw_input('Enter Fname of student to view: ')
        for (i,student,) in enumerate(Students): 
            if viewInput == 'First Name': 
                print Students[i] 
    
    def viewAllStudents(): 
        for x in Students: 
            for k,v in x.iteritems(): 
                if k == "First Name": 
                    print v 
    
    userInput = 0 
    while userInput != -1: 
        printmenu() 
        userInput = int(raw_input('choose option from menu. Enter -1 to quit: ')) 
        if userInput == 1: 
            addStudent() 
        elif userInput == 2: 
            removeStudent() 
        elif userInput == 3: 
            viewStudent() 
        elif userInput == 4: 
            viewAllStudents() 
        elif userInput == -1: 
            print 'End of program' 
        else: 
            print 'Sorry' ,userInput, 'is not a valid option. Try again.'
  6. #4
  7. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,841
    Rep Power
    480
    Try this version of your program. And read the new comments.
    Code:
    import pprint
    import collections
    
    Students = []
    
    def no():
        print("defaultdict: you've tried another invalid key!")
    
    def complain(Student):
        print 'type(Student)',type(Student) # Student is a dictionary.
        print 'Access Student as a dictionary using a valid key.  The keys are'
        pprint.pprint(set(Student.keys()))
        print '"First Name" is an invalid key'
    
    def printmenu():
        print 'MENU'
        print '1. Add Student'
        print '2. Remove Student'
        print '3. View Student'
        print '4. View All Students'
        print 'q. quit'  # quit is a menu item.
    
    def addStudent():
        # These variable names are meaningless.
        # I like meaningless variable names in short contexts.
        # I like short meaningless variable names.  1 character is short.
        addInput1 = raw_input('enter first name of student ')
        addInput2 = raw_input('enter last name of student ')
        addInput3 = raw_input('enter the age of student ')
        Student = collections.defaultdict(no)
        Student.update({'FName':addInput1,'LName':addInput2,'Age':addInput3})
        Students.append(Student)
        ############ return Students   # why bother returning a value you don't use?
    
    def removeStudent():
        removeInput = raw_input('enter name of student to R: ')
        for (i,Student,) in enumerate(Students):
            complain(Student)
            if Student['First Name'] == removeInput:
                del Students[i]
    
    def viewStudent(): # wrong Right!
        viewInput = raw_input('Enter Fname of student to view: ')
        for student in Students: # list index unnecessary (removed enumerate)
            complain(student)
            print('I repaired the next access')
            if viewInput == student['FName']: # I fixed this for you
                pprint.pprint(student)
    
    def viewAllStudents():
        for x in Students:
            print x['FName']
            #pprint.pprint(x)  # use pprint.
            #        for (k,v,) in x.iteritems():
            #            if k == "First Name":
            #                print v
    
    userInput = 0
    while userInput != 'q':
        printmenu()
        # Conversion to integer makes trouble.  Avoid it.
        userInput = raw_input('choose option from menu.: ')
        if userInput == '1':
            addStudent()
        elif userInput == '2':
            removeStudent()
        elif userInput == '3':
            viewStudent()
        elif userInput == '4':
            viewAllStudents()
        elif userInput != 'q':
            print 'Sorry' ,userInput, 'is not a valid option. Try again.'
    
    print 'End of program'
    enumerate
    Code:
    >>> L = 'abc'
    >>> for i in range(len(L)):  # an exceedingly common pattern
    ...     o = L[i]
    ...     print(i,o)
    ... 
    (0, 'a')
    (1, 'b')
    (2, 'c')
    >>> for (i,o,) in enumerate('abc'):  # use enumerate instead
    ...    print(i,o)
    ...    
    (0, 'a')
    (1, 'b')
    (2, 'c')
    >>>
    Glad you investigated pdb and pprint.
    [code]Code tags[/code] are essential for python code and Makefiles!
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    54
    Rep Power
    2
    Hi,

    Went through the updated codes from you. With regards to def viewStudent, I am looking to have a print out similar to the following:

    Code:
    FName Ashley
    LName Cole
    Age 20
    Your amended codes printed out the following when def viewStudent was called:

    Code:
    type(Student) 
    <type 'collections.defaultdict'>
    Access Student as a dictionary using a valid key.  
    The keys are set(['Age', 'FName', 'LName'])
    "First Name" is an invalid key
    I repaired the next access
    defaultdict(<function no at 0x02C6AB30>, 
    {'LName': 'q', 'Age': 'q', 'FName': 'q'})
    It is coming from the newly defined function 'complain' containing the prints above. I believe the print is a guide on what's going on in the background though tbh am a little confused on parts such as <function no at 0x02C6AB30>.

    Also with regards to import pprint and collection, I was unable to get information on collection. Regarding pprint, I tried the following:

    Code:
    import pprint 
    lister = [1,2,3] 
    
    for x in lister: 
        print x 
    
    for y in lister: 
        pprint.pprint (y)
    Both of the print output is the same. I don't see how pprint makes a diff.. Thanks for help.
  10. #6
  11. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,841
    Rep Power
    480
    I was trying to show that you should program with purpose and care. In your post you used at least three different dictionary keys to represent first name.

    You stored the first name into the dictionary with key 'FName', and that is the key you need to use elsewhere.
    Code:
        Student ={'FName':addInput1,'LName':addInput2,'Age':addInput3}
    In both viewAllStudents and removeStudent you pretended the key is 'First Name'
    Code:
            if Student['First Name'] == removeInput: 
    #...
                if k == "First Name":
    In a prompt, and this isn't logically important, you called it 'Fname'.
    Code:
        viewInput = raw_input('Enter Fname of student to view: ')
    These are completely different!
    Code:
    >>> hash('FName')
    8573798989201560054
    >>> hash('Fname')
    3680662843094458262
    >>> hash('First Name')
    2455262388738096017
    >>>


    pprint helps when the output is long. Remember this lesson years before (relative to python initiation) I learned it.
    Code:
    >>> print(os.listdir(os.curdir) ) #unreadable
    ['.X0-lock', 'unity_support_test.0', '.esd-1000', 'CRX_75DAF8CB7768', 'p.pyc', 'psss-temp.py', '#q.py#', '#z.ijs#', '.org.chromium.Chromium.xte7LI', 'wut.png', '.#q.py', 'pulse-NfrGN9Z3Yir3', '.#z.ijs', 'Makefile', 'ssh-imuon5a65Hru', 'tmpIqN2uF', '.ICE-unix', 'pulse-PKdhtXMmr18n', 'p.py', '.X11-unix', 'a']
    >>> 
    >>> 
    >>> pprint.pprint(os.listdir(os.curdir))  # with pprint
    ['.X0-lock',
     'unity_support_test.0',
     '.esd-1000',
     'CRX_75DAF8CB7768',
     'p.pyc',
     'psss-temp.py',
     '#q.py#',
     '#z.ijs#',
     '.org.chromium.Chromium.xte7LI',
     'wut.png',
     '.#q.py',
     'pulse-NfrGN9Z3Yir3',
     '.#z.ijs',
     'Makefile',
     'ssh-imuon5a65Hru',
     'tmpIqN2uF',
     '.ICE-unix',
     'pulse-PKdhtXMmr18n',
     'p.py',
     '.X11-unix',
     'a']
    >>>
    [code]Code tags[/code] are essential for python code and Makefiles!
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    54
    Rep Power
    2
    Okie. Actually through my code I used the variable as 'First Name' constantly. I changed it to 'FName' when posting here for me to shorten the words(to view better when I type in the codes inside the reply box). Seems I made errors in not making a uniform change. Sorry & tnks for tip.

    Regards to def viewStudent still little lost though..

    Code:
    def viewStudent(): 
        viewInput = raw_input('Enter First Name of student to view: ') 
        for student in Students: 
             if viewInput == student['First Name']: 
             pprint.pprint(student)
    I derived the above code from your guide. But the print out comes out as follows (I input information in this order, First Name, Last Name and then Age. Seems the print out comes out jumbled up though. Believe I should use sorted. Yet to figure it out. Working on it):

    Code:
     ('Age': 'a',
     'First Name': 'a',
     'Last Name': 'a'}
    I'm trying to obtain it as:

    Code:
    First Name: a
    Last Name: a
    Age: a
    Is it possible to do it without the curly braces and commas? Thank you.
  14. #8
  15. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,841
    Rep Power
    480
    Code:
    example = {
        'Address': 'a',
        'Age': 'a',
        'E-mail': 'a',
        'First Name': 'a',
        'Last Name': 'a',
        'Program': 'a'
        }
    
    def custom_print_dict(d,keys):
        for key in keys:
            print('%s: %s'%(str(key),str(d[key])))
    
    custom_print_dict(example,('First Name','Last Name','Age'))
    [code]Code tags[/code] are essential for python code and Makefiles!
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    54
    Rep Power
    2
    Got it. Thanks for help and patience.

    Code:
    ('%s:%s'%
    This is new to me yet again. But played around and figured that it's what you have used to format the print out. If I had wanted a comma in it, I could have made is as follows:

    Code:
    ('%s:%s,'%
    Hope am interpreting it right. Seems useful. Tnks again.

IMN logo majestic logo threadwatch logo seochat tools logo