Re: [Tutor] Remove a dictionary entry

2010-09-19 Thread M. 427
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

2010-09-19 Thread Peter Otten
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

2010-09-19 Thread Peter Otten
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

2010-09-18 Thread M. 427
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

2010-09-18 Thread Alan Gauld


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

2010-09-18 Thread Peter Otten
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

2010-09-18 Thread Alan Gauld


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

2010-09-18 Thread Steven D'Aprano
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

2010-09-18 Thread bob gailer
 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

2010-09-17 Thread M. 427
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

2010-09-17 Thread Joel Goldstick
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

2010-09-17 Thread bob gailer

 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

2010-09-17 Thread bob gailer

 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

2010-09-17 Thread bob gailer

 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