Re: [Tutor] Remove a dictionary entry
Version 4 : (2 steps) # step 1 : list keys of unwanted rows sck=[] # list of single children keys in dictionary for k in d.keys() : if len(d[k]) 2 : sck.append(k) # step 2 : delete all d rows whose key is listed in sck while len(sck) 0 : del d[sck.pop()] This works. Is this the optimal pythonic way of doing it? Mr. 427 Le vendredi 17 septembre 2010 à 21:36 -0400, bob gailer a écrit : On 9/17/2010 9:21 PM, M. 427 wrote: Thank you, After reading the following documentations http://docs.python.org/tutorial/datastructures.html#looping-techniques http://docs.python.org/tutorial/controlflow.html#for-statements I ended up with this : Version 3 : for i,row in d[:].iteritems() : # BUG : TypeError: unhashable type if len(row) 2 : del d[i] Still buggy... Any lead for this error message? Is a slice unhashable? Am I looking in the right direction for this task? Where did you see [:] after a dict? [:] is slicing, and applies to a sequence not a mapping. Also note the warning Using iteritems() while adding or deleting entries in the dictionary may raise a RuntimeError or fail to iterate over all entries. You should get a list rather than an iterator of all key-value pairs then iterate over that list. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Remove a dictionary entry
M. 427 wrote: Version 4 : (2 steps) # step 1 : list keys of unwanted rows sck=[] # list of single children keys in dictionary for k in d.keys() : if len(d[k]) 2 : sck.append(k) # step 2 : delete all d rows whose key is listed in sck while len(sck) 0 : del d[sck.pop()] This works. Is this the optimal pythonic way of doing it? Ceterum censeo: the pythonic way is to make a copy: d = dict((k, v) for k, v in d.iteritems() if len(v) 1) As an optimization, if the dictionary is huge and there are relatively few items to be deleted you may fall back to the 2-step approach. I would write it delenda = [k for k, v in d.iteritems() if len(v) 2] for k in delenda: del d[k] Peter ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Remove a dictionary entry
Steven D'Aprano wrote: On Sat, 18 Sep 2010 07:13:13 pm Peter Otten wrote: You should never iterate over a list or dictionary and add or remove items to it at the same time. That is a recipe for disaster even if it doesn't fail explicitly. That's a bit strong. It's quite possible to modify lists safely and correctly while iterating over them with a little bit of care. You're of course not the intended audience of my advice. You know, for decades people were able to program in languages like C and Pascal and assembly, often on machines with tiny amounts of memory. When your machine has 64K of memory, and the OS and application uses half of it, you don't have the luxury of making a copy of a 20K list before modifying it. Back when I was a lad, we learned how to modify lists in place. It isn't hard. *wink* When you do that you are usually operating on an abstraction level below Python. Even in Python, it is sometimes necessary to modify lists and even dicts in place while iterating over them. 98% of the time, making a copy is faster, simpler and more efficient, but learning how to safely modify data structures in place is a valuable skill to have. If you have a huge list that you can only modify in place you may have chosen the wrong data structure. But I'm just talking about general principles here. In most cases, stick to Peter's advice to make a copy. Hey, I can agree with that ;) Peter ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Remove a dictionary entry
Thank you, After reading the following documentations http://docs.python.org/tutorial/datastructures.html#looping-techniques http://docs.python.org/tutorial/controlflow.html#for-statements I ended up with this : Version 3 : for i,row in d[:].iteritems() : # BUG : TypeError: unhashable type if len(row) 2 : del d[i] Still buggy... Any lead for this error message? Is a slice unhashable? Am I looking in the right direction for this task? Mr. 427 Le vendredi 17 septembre 2010 à 20:50 -0400, bob gailer a écrit : Please always reply-all so a copy goes to the tutor list. On 9/17/2010 6:20 PM, M. 427 wrote: Thank you very much for your answer. I wanted to know the pythonic way of doing this, so I did not post my buggy trial which was : version 1 : for row in d : if len(row) == 1 : del row # WRONG Version 2 : for i,row in d : if len(row) == 1 : del d(i) # BUG : Syntax error Thank you for posting code. In the future do so initially. It helps us know where to help. It looks like you learned from version 1. When you get a syntax error check the manual. When you look at del in: Python v2.6.4 documentation - The Python Standard Library - 6.8 Mapping Type - dict you will see d[key] - compare that to what you wrote in version 2. -- Bob Gailer 919-636-4239 Chapel Hill NC ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Remove a dictionary entry
M. 427 4...@free.fr wrote I ended up with this : Version 3 : for i,row in d[:].iteritems() : # BUG : TypeError: unhashable type if len(row) 2 : del d[i] You are getting too complicated. You don't need the slice and you don't need iteritems. You have a dictionary. When you iterate over a dictionary what do you get? Don't know? Try it:: for x in {1:'foo',2:'bar'}: print x ... 1 2 So we get the keys. Now how do we use the keys to get the list? Standard dictionary access: print d[1] foo You know how to test the lenth of the list and delete the list so put that together as you did before: for row in d : # row is actually the key if len(row) == 1 :# so use the key to get the real row del row # WRONG #' and delete the row, again using the key HTH, -- Alan Gauld Author of the Learn to Program web site http://www.alan-g.me.uk/ ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Remove a dictionary entry
M. 427 wrote: (I am very new to python) I built a dictionary d={} of lists similar to this : d = { 'a': ['apricot', 'apple'], 'b': ['beach', 'bear', 'bottle'], 'c': ['cold', 'cook', 'coleslaw'], 'd': ['deep'], 'e': ['expression', 'elephant'] } Now i want to go through this dictionary and remove all rows containing only one entry. How should I do that? You should never iterate over a list or dictionary and add or remove items to it at the same time. That is a recipe for disaster even if it doesn't fail explicitly. Instead create a new dictionary that contains only the items you are interested in: d = { ... 'a': ['apricot', 'apple'], ... 'b': ['beach', 'bear', 'bottle'], ... 'c': ['cold', 'cook', 'coleslaw'], ... 'd': ['deep'], ... 'e': ['expression', 'elephant'] ... } result = {} for k, v in d.iteritems(): ... if len(v) 1: ... result[k] = v ... import pprint pprint.pprint(result) {'a': ['apricot', 'apple'], 'b': ['beach', 'bear', 'bottle'], 'c': ['cold', 'cook', 'coleslaw'], 'e': ['expression', 'elephant']} Peter PS: Instead of using the pretty print module pprint I could have typed result {'a': ['apricot', 'apple'], 'c': ['cold', 'cook', 'coleslaw'], 'b': ['beach', 'bear', 'bottle'], 'e': ['expression', 'elephant']} The only difference is that it looks messier. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Remove a dictionary entry
Alan Gauld alan.ga...@btinternet.com wrote I ended up with this : Version 3 : for i,row in d[:].iteritems() : # BUG : TypeError: unhashable type if len(row) 2 : del d[i] You are getting too complicated. You don't need the slice and you don't need iteritems. You have a dictionary. When you iterate over a dictionary what do you get? Don't know? Try it:: for x in {1:'foo',2:'bar'}: print x ... 1 2 So we get the keys. Now how do we use the keys to get the list? Standard dictionary access: print d[1] foo You know how to test the lenth of the list and delete the list so put that together as you did before: for row in d : # row is actually the key if len(row) == 1 :# so use the key to get the real row del row # WRONG #' and delete the row, again using the key Oops, as Peter pointed out that won't work because its changing the iterable while we iterate. (I actually thought it would be OK because the for would use a copy of the keys() list, but I was wrong...) But you can fix that with a list() call: for row in list(d) : # generates a new list of the dict keys if len(d[row]) == 1 :# so use the key to get the real row del d[row] HTH, -- Alan Gauld Author of the Learn to Program web site http://www.alan-g.me.uk/ HTH, -- Alan Gauld Author of the Learn to Program web site http://www.alan-g.me.uk/ ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Remove a dictionary entry
On Sat, 18 Sep 2010 07:13:13 pm Peter Otten wrote: You should never iterate over a list or dictionary and add or remove items to it at the same time. That is a recipe for disaster even if it doesn't fail explicitly. That's a bit strong. It's quite possible to modify lists safely and correctly while iterating over them with a little bit of care. You know, for decades people were able to program in languages like C and Pascal and assembly, often on machines with tiny amounts of memory. When your machine has 64K of memory, and the OS and application uses half of it, you don't have the luxury of making a copy of a 20K list before modifying it. Back when I was a lad, we learned how to modify lists in place. It isn't hard. *wink* Even in Python, it is sometimes necessary to modify lists and even dicts in place while iterating over them. 98% of the time, making a copy is faster, simpler and more efficient, but learning how to safely modify data structures in place is a valuable skill to have. But I'm just talking about general principles here. In most cases, stick to Peter's advice to make a copy. -- Steven D'Aprano ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Remove a dictionary entry
Yet another way is to iterate thru the dict collecting a list of keys of items to be deleted. Then iterate thru that list deleting from the dict. -- Bob Gailer 919-636-4239 Chapel Hill NC ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] Remove a dictionary entry
Hello, (I am very new to python) I built a dictionary d={} of lists similar to this : d = { 'a': ['apricot', 'apple'], 'b': ['beach', 'bear', 'bottle'], 'c': ['cold', 'cook', 'coleslaw'], 'd': ['deep'], 'e': ['expression', 'elephant'] } Now i want to go through this dictionary and remove all rows containing only one entry. How should I do that? Question 2 : where should I have found this answer myself? (apart from here) Thank you for your help. Mr. 427 ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Remove a dictionary entry
On Fri, Sep 17, 2010 at 9:08 AM, M. 427 4...@free.fr wrote: Hello, (I am very new to python) I built a dictionary d={} of lists similar to this : d = { 'a': ['apricot', 'apple'], 'b': ['beach', 'bear', 'bottle'], 'c': ['cold', 'cook', 'coleslaw'], 'd': ['deep'], 'e': ['expression', 'elephant'] } Now i want to go through this dictionary and remove all rows containing only one entry. How should I do that? You can loop through all the entries in d, and remove the entries that have length one. Hope that isn't too much of a hint Question 2 : where should I have found this answer myself? (apart from here) Thank you for your help. Mr. 427 ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor -- Joel Goldstick ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Remove a dictionary entry
On 9/17/2010 9:08 AM, M. 427 wrote: Hello, (I am very new to python) I built a dictionary d={} of lists similar to this : d = { 'a': ['apricot', 'apple'], 'b': ['beach', 'bear', 'bottle'], 'c': ['cold', 'cook', 'coleslaw'], 'd': ['deep'], 'e': ['expression', 'elephant'] } Now i want to go through this dictionary and remove all rows containing only one entry. How should I do that? We like to help when you tell us what part(s) of the answer you know. There are 4 things involved here: 1 - How to get a list of all the key-value pairs in a dictionary. 2 - How to loop thru that list. 3 - How to get the length of a value's list. 4 - How to test that for equal to 1. 5- How to delete a dictionary entry knowing the key. Which of those do you know? Which do you need help with? Question 2 : where should I have found this answer myself? (apart from here) It is hard to give a specific answer since we don't know what you don't know. I suspect most tutorials will give you the answers. In the Python Reference /6.8 Mapping Type - dict /it tells you the answers to 1 and 5. In the Python Reference /6.6.4. Mutable Sequence Types/ it tells you the answer to 3. In the Python Reference /5.9 Comparisons/ it tells you the answer to 4. Regarding 3 there are several ways to loop through a sequence. Tutorials explain these. -- Bob Gailer 919-636-4239 Chapel Hill NC ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Remove a dictionary entry
Please always reply-all so a copy goes to the tutor list. On 9/17/2010 6:20 PM, M. 427 wrote: Thank you very much for your answer. I wanted to know the pythonic way of doing this, so I did not post my buggy trial which was : version 1 : for row in d : if len(row) == 1 : del row # WRONG Version 2 : for i,row in d : if len(row) == 1 : del d(i) # BUG : Syntax error Thank you for posting code. In the future do so initially. It helps us know where to help. It looks like you learned from version 1. When you get a syntax error check the manual. When you look at del in: Python v2.6.4 documentation - The Python Standard Library - 6.8 Mapping Type - dict you will see d[key] - compare that to what you wrote in version 2. -- Bob Gailer 919-636-4239 Chapel Hill NC ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Remove a dictionary entry
On 9/17/2010 9:21 PM, M. 427 wrote: Thank you, After reading the following documentations http://docs.python.org/tutorial/datastructures.html#looping-techniques http://docs.python.org/tutorial/controlflow.html#for-statements I ended up with this : Version 3 : for i,row in d[:].iteritems() : # BUG : TypeError: unhashable type if len(row) 2 : del d[i] Still buggy... Any lead for this error message? Is a slice unhashable? Am I looking in the right direction for this task? Where did you see [:] after a dict? [:] is slicing, and applies to a sequence not a mapping. Also note the warning Using iteritems() while adding or deleting entries in the dictionary may raise a RuntimeError or fail to iterate over all entries. You should get a list rather than an iterator of all key-value pairs then iterate over that list. -- Bob Gailer 919-636-4239 Chapel Hill NC ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor