Friday, March 5, 2010

comp.lang.python - 25 new messages in 8 topics - digest

comp.lang.python
http://groups.google.com/group/comp.lang.python?hl=en

comp.lang.python@googlegroups.com

Today's topics:

* Slicing [N::-1] - 5 messages, 3 authors
http://groups.google.com/group/comp.lang.python/t/add9aa920b55eacc?hl=en
* Conditional based on whether or not a module is being used - 1 messages, 1
author
http://groups.google.com/group/comp.lang.python/t/ee22c223fa73a429?hl=en
* Draft PEP on RSON configuration file format - 4 messages, 4 authors
http://groups.google.com/group/comp.lang.python/t/09ce33197b330e90?hl=en
* Generic singleton - 3 messages, 2 authors
http://groups.google.com/group/comp.lang.python/t/9228a3763eb552b3?hl=en
* isinstance(False, int) - 4 messages, 4 authors
http://groups.google.com/group/comp.lang.python/t/27beadbbfad9243d?hl=en
* My four-yorkshireprogrammers contribution - 1 messages, 1 author
http://groups.google.com/group/comp.lang.python/t/dea5c94f3d058e26?hl=en
* best practices: is collections.defaultdict my friend or not? - 6 messages, 4
authors
http://groups.google.com/group/comp.lang.python/t/4bfdc60d3f58c960?hl=en
* A "scopeguard" for Python - 1 messages, 1 author
http://groups.google.com/group/comp.lang.python/t/8c752e871801c223?hl=en

==============================================================================
TOPIC: Slicing [N::-1]
http://groups.google.com/group/comp.lang.python/t/add9aa920b55eacc?hl=en
==============================================================================

== 1 of 5 ==
Date: Fri, Mar 5 2010 2:12 pm
From: Robert Kern


On 2010-03-05 13:10 PM, Robert Kern wrote:
> On 2010-03-05 12:28 PM, Steven D'Aprano wrote:
>> On Fri, 05 Mar 2010 18:12:05 +0000, Arnaud Delobelle wrote:
>>
>>>>>> l = range(10)
>>>>>> l
>>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>>>> l[7::-1]
>>> [7, 6, 5, 4, 3, 2, 1, 0]
>>>>>> [l[i] for i in range(7, -1, -1)]
>>> [7, 6, 5, 4, 3, 2, 1, 0]
>>
>> Where does the first -1 come from? Slices are supposed to have default
>> values of 0 and len(seq):
>
> Rather, they have 0 and len(seq), respectively, when the step is
> positive, and len(seq)-1 and -1 when the step is negative.

Well, not entirely true. [N:-1:-1] obviously doesn't work for this. Rather,
leaving the second argument in the slice empty means "go to the end if step > 0
or go to the beginning if step < 0". There is no explicit translation of the
latter because there is no numerical index for the element before the first element.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco

== 2 of 5 ==
Date: Fri, Mar 5 2010 4:09 pm
From: Mensanator


On Mar 5, 3:42 pm, Gary Herron <gher...@islandtraining.com> wrote:
> Mensanator wrote:
>
> > The only way to get a 0 from a reverse range() is to have a bound of
> > -1.
>
> Not quite.  An empty second bound goes all the way to the zero index:

Not the same thing. You're using the bounds of the slice index.
I was refering to the bounds of the range() function.

>>> for a in range(9,-9,-1):print(a,end=' ')
9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8

To get that to stop at 0, you use a -1 as the bounds:

>>> for a in range(9,-1,-1):print(a,end=' ')
9 8 7 6 5 4 3 2 1 0

Your slice notation only works if the last (first?) number in
the range happens to be 0. What if the range bounds were variables?
You may still want to force the range's last number to be 0 by
using a constant like range(a,-1,-1) rather than just take
the last number of range(a,b,-1) by using slice notation.

>
>  >>> range(9)[2::-1]
> [2, 1, 0]
>
> Gary Herron


== 3 of 5 ==
Date: Fri, Mar 5 2010 4:34 pm
From: Gary Herron


Mensanator wrote:
> On Mar 5, 3:42 pm, Gary Herron <gher...@islandtraining.com> wrote:
>
>> Mensanator wrote:
>>
>>
>>> The only way to get a 0 from a reverse range() is to have a bound of
>>> -1.
>>>
>> Not quite. An empty second bound goes all the way to the zero index:
>>
>
> Not the same thing. You're using the bounds of the slice index.
> I was refering to the bounds of the range() function.
>
>
>>>> for a in range(9,-9,-1):print(a,end=' ')
>>>>
> 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8
>
> To get that to stop at 0, you use a -1 as the bounds:
>
>
>>>> for a in range(9,-1,-1):print(a,end=' ')
>>>>
> 9 8 7 6 5 4 3 2 1 0
>
> Your slice notation only works if the last (first?) number in
> the range happens to be 0. What if the range bounds were variables?
> You may still want to force the range's last number to be 0 by
> using a constant like range(a,-1,-1) rather than just take
> the last number of range(a,b,-1) by using slice notation.
>

All true and valid of course, but I was just contridicting the "the
ONLY way to get a 0" (emphasis mine) part of the statement.

Gary Herron

>
>> >>> range(9)[2::-1]
>> [2, 1, 0]
>>
>> Gary Herron
>>

== 4 of 5 ==
Date: Fri, Mar 5 2010 6:09 pm
From: Mensanator


On Mar 5, 6:34 pm, Gary Herron <gher...@islandtraining.com> wrote:
> Mensanator wrote:
> > On Mar 5, 3:42 pm, Gary Herron <gher...@islandtraining.com> wrote:
>
> >> Mensanator wrote:
>
> >>> The only way to get a 0 from a reverse range() is to have a bound of
> >>> -1.
>
> >> Not quite.  An empty second bound goes all the way to the zero index:
>
> > Not the same thing. You're using the bounds of the slice index.
> > I was refering to the bounds of the range() function.
>
> >>>> for a in range(9,-9,-1):print(a,end=' ')
>
> > 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8
>
> > To get that to stop at 0, you use a -1 as the bounds:
>
> >>>> for a in range(9,-1,-1):print(a,end=' ')
>
> > 9 8 7 6 5 4 3 2 1 0
>
> > Your slice notation only works if the last (first?) number in
> > the range happens to be 0. What if the range bounds were variables?
> > You may still want to force the range's last number to be 0 by
> > using a constant like range(a,-1,-1) rather than just take
> > the last number of range(a,b,-1) by using slice notation.
>
> All true  and valid of course, but I was just contridicting the "the
> ONLY way to get a 0" (emphasis mine) part of the statement.

Does it still contradict if you do not use the '::' as the OP
requested?

>
> Gary Herron
>
>
>
>
>
> >>  >>> range(9)[2::-1]
> >> [2, 1, 0]
>
> >> Gary Herron- Hide quoted text -
>
> - Show quoted text -- Hide quoted text -
>
> - Show quoted text -

== 5 of 5 ==
Date: Fri, Mar 5 2010 7:05 pm
From: Gary Herron


Mensanator wrote:
> On Mar 5, 6:34 pm, Gary Herron <gher...@islandtraining.com> wrote:
>
>> Mensanator wrote:
>>
>>> On Mar 5, 3:42 pm, Gary Herron <gher...@islandtraining.com> wrote:
>>>
>>>> Mensanator wrote:
>>>>
>>>>> The only way to get a 0 from a reverse range() is to have a bound of
>>>>> -1.
>>>>>
>>>> Not quite. An empty second bound goes all the way to the zero index:
>>>>
>>> Not the same thing. You're using the bounds of the slice index.
>>> I was refering to the bounds of the range() function.
>>>
>>>>>> for a in range(9,-9,-1):print(a,end=' ')
>>>>>>
>>> 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8
>>>
>>> To get that to stop at 0, you use a -1 as the bounds:
>>>
>>>>>> for a in range(9,-1,-1):print(a,end=' ')
>>>>>>
>>> 9 8 7 6 5 4 3 2 1 0
>>>
>>> Your slice notation only works if the last (first?) number in
>>> the range happens to be 0. What if the range bounds were variables?
>>> You may still want to force the range's last number to be 0 by
>>> using a constant like range(a,-1,-1) rather than just take
>>> the last number of range(a,b,-1) by using slice notation.
>>>
>> All true and valid of course, but I was just contridicting the "the
>> ONLY way to get a 0" (emphasis mine) part of the statement.
>>
>
> Does it still contradict if you do not use the '::' as the OP
> requested?
>

Not to my knowledge... I believe your statement is true in all cases
which explicitly state the stop value.


>
>> Gary Herron
>>
>>
>>
>>
>>
>>
>>>> >>> range(9)[2::-1]
>>>> [2, 1, 0]
>>>>
>>>> Gary Herron- Hide quoted text -
>>>>
>> - Show quoted text -- Hide quoted text -
>>
>> - Show quoted text -
>>
>
>


==============================================================================
TOPIC: Conditional based on whether or not a module is being used
http://groups.google.com/group/comp.lang.python/t/ee22c223fa73a429?hl=en
==============================================================================

== 1 of 1 ==
Date: Fri, Mar 5 2010 2:16 pm
From: Terry Reedy


On 3/5/2010 4:29 PM, Pete Emerson wrote:
> On Mar 5, 1:14 pm, Chris Rebert<c...@rebertia.com> wrote:

> I want to write other modules, and my thinking is that it makes sense
> for those modules to use the "logger" module to do the logging, if and
> only if the parent using the other modules is also using the logger
> module.
>
> In other words, I don't want to force someone to use the "logger"
> module just so they can use my other modules, even if the "logger"
> module is installed ... but I also want to take advantage of it if I'm
> using it.
>
> Now that I've written that, I'm not sure that makes a whole lot of
> sense. It seems like I could say, "hey, this person has the 'logger'
> module available, let's use it!".

Except in unusual cases, where merely importing a modules uses
substantial resources, I would say that if it is available, use it.


==============================================================================
TOPIC: Draft PEP on RSON configuration file format
http://groups.google.com/group/comp.lang.python/t/09ce33197b330e90?hl=en
==============================================================================

== 1 of 4 ==
Date: Fri, Mar 5 2010 2:45 pm
From: aahz@pythoncraft.com (Aahz)


In article <7xwrxv4vv7.fsf@ruckus.brouhaha.com>,
Paul Rubin <no.email@nospam.invalid> wrote:
>
>ReST is another abomination that should never have gotten off the
>ground. It is one of the reasons I react so negatively to your
>config format proposal. It just sounds like more of the same.

Really? What should we use instead of reST?
--
Aahz (aahz@pythoncraft.com) <*> http://www.pythoncraft.com/

"Many customs in this life persist because they ease friction and promote
productivity as a result of universal agreement, and whether they are
precisely the optimal choices is much less important." --Henry Spencer


== 2 of 4 ==
Date: Fri, Mar 5 2010 5:06 pm
From: Gregory Ewing


Steven D'Aprano wrote:

> I use footnotes all the time[1] in plain text documents and emails. I
> don't think there's anything bizarre about it at all.

It's not the use of footnotes I'm talking about, it's
the cryptic character sequences used to mark them up
in ReST. Nobody would come up with them on their own
without having read the fine print of an ReST manual.

--
Greg


== 3 of 4 ==
Date: Fri, Mar 5 2010 5:15 pm
From: Robert Kern


On 2010-03-05 17:59 PM, Chris Rebert wrote:
> On Fri, Mar 5, 2010 at 2:45 PM, Aahz <aahz@pythoncraft.com
> <mailto:aahz@pythoncraft.com>> wrote:
> > In article <7xwrxv4vv7.fsf@ruckus.brouhaha.com
> <mailto:7xwrxv4vv7.fsf@ruckus.brouhaha.com>>,
> > Paul Rubin <no.email@nospam.invalid> wrote:
> >>
> >>ReST is another abomination that should never have gotten off the
> >>ground. It is one of the reasons I react so negatively to your
> >>config format proposal. It just sounds like more of the same.
> >
> > Really? What should we use instead of reST?
>
> Markdown, Textile, or possibly Creole; reST has so little use outside of
> Python as to be nearly Python-specific.
> It'd be nice not to have to learn yet another markup language without
> good reason.

I believe ReST predates all of those mentioned.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco

== 4 of 4 ==
Date: Fri, Mar 5 2010 5:10 pm
From: Paul Rubin


Robert Kern <robert.kern@gmail.com> writes:
>> Markdown, Textile, or possibly Creole;...
> I believe ReST predates all of those mentioned.

Texinfo and POD are certainly older than ReST. I'm not sure about
MediaWiki markup, but it's gotten so much traction that Markdown
should probably be abandoned in its favor even if Markdown is older.

==============================================================================
TOPIC: Generic singleton
http://groups.google.com/group/comp.lang.python/t/9228a3763eb552b3?hl=en
==============================================================================

== 1 of 3 ==
Date: Fri, Mar 5 2010 3:07 pm
From: Steven D'Aprano


On Fri, 05 Mar 2010 16:25:46 -0500, Terry Reedy wrote:

> On 3/5/2010 1:01 PM, Steven D'Aprano wrote:
>> On Fri, 05 Mar 2010 11:57:13 -0500, Terry Reedy wrote:
>>
>>> On 3/4/2010 10:32 PM, Steven D'Aprano wrote:
>>>
>>>> Python does have it's own singletons, like None, True and False.
>>>
>>> True and False are not singletons.
>>
>> Duotons? Doubletons?
>
> The latter is what I use.

The Wikipedia article on Singleton states that it is acceptable to
generalise "Singleton" to allow multiple instances.

http://en.wikipedia.org/wiki/Singleton_pattern

While Doubleton or even Tripleton sound cute, once you get to large
counts it all starts getting ugly and horrible. "Polyton"? Blah.


[...]
> This is your strongest argument. It has nothing to do in particular with
> (the dubious analogy with) bool. Here is a draft of what you might post
> to python-ideas list, or even the tracker.

Oh, you have misunderstood me. I'm not particularly concerned about
NoneType's behaviour, and certainly not concerned enough to champion the
change against any opposition (let alone through the moratorium!). I
wanted to understand why the difference existed.

Python has at least two other singletons, Ellipsis and NotImplemented,
and both behave like None.

--
Steven


== 2 of 3 ==
Date: Fri, Mar 5 2010 5:39 pm
From: Gregory Ewing


I think the important difference between None and booleans
wrt singleton behaviour is that things are often compared
with None using "is", so it's quite important that there
only be one instance of NoneType around, and it makes
sense not to give people the false impression that they
can create another one.

Re-using predefined True and False instances is more of
a performance optimisation, however -- they're not usually
compared for identity, or even compared at all for that
matter. So there's no particular reason to disallow
calling bool().

In fact, there's an excellent reason to *allow* calling
it: not only is bool a type, it's also often used as a
function to coerce things to a boolean value:

>>> bool(['hello'])
True

There's no equivalent reason to make NoneType callable,
as coercing something to None makes very little sense.

--
Greg


== 3 of 3 ==
Date: Fri, Mar 5 2010 5:45 pm
From: Gregory Ewing


Steven D'Aprano wrote:

> While Doubleton or even Tripleton sound cute, once you get to large
> counts it all starts getting ugly and horrible. "Polyton"? Blah.

Tupleton?

--
Greg

==============================================================================
TOPIC: isinstance(False, int)
http://groups.google.com/group/comp.lang.python/t/27beadbbfad9243d?hl=en
==============================================================================

== 1 of 4 ==
Date: Fri, Mar 5 2010 3:09 pm
From: Steven D'Aprano


On Fri, 05 Mar 2010 15:58:01 -0500, Jack Diederich wrote:

>>> So, the pythonic way to check for True/False should be:
>>>
>>>>>> 1 is True
>>> False
>>
>> Why do you need to check for True/False?
>>
>>
> You should never check for "is" False/True but always check for
> equality. The reason is that many types support the equality (__eq__)
> and boolen (__bool__ in 3x) protocols. If you check equality these will
> be invoked, if you check identity ("is") they won't.

Never say never.

If you specifically want to test for True or False themselves, accepting
no substitutes, then using "is" is the obvious way, and using "==" is
clearly and obviously wrong because it does accept substitutes:

>>> 1.0 == True
True
>>> decimal.Decimal(0, 1) == False
True

--
Steven


== 2 of 4 ==
Date: Fri, Mar 5 2010 3:48 pm
From: Jack Diederich


On Fri, Mar 5, 2010 at 6:09 PM, Steven D'Aprano
<steve@remove-this-cybersource.com.au> wrote:
> On Fri, 05 Mar 2010 15:58:01 -0500, Jack Diederich wrote:
>
>>>> So, the pythonic way to check for True/False should be:
>>>>
>>>>>>> 1 is True
>>>> False
>>>
>>> Why do you need to check for True/False?
>>>
>>>
>> You should never check for "is" False/True but always check for
>> equality.  The reason is that many types support the equality (__eq__)
>> and boolen (__bool__ in 3x) protocols.  If you check equality these will
>> be invoked, if you check identity ("is") they won't.
>
> Never say never.
>
> If you specifically want to test for True or False themselves, accepting
> no substitutes, then using "is" is the obvious way, and using "==" is
> clearly and obviously wrong because it does accept substitutes:
>
>>>> 1.0 == True
> True
>>>> decimal.Decimal(0, 1) == False
> True


Yes, obviously if you _really_ mean to test if something has the
object identity of True or False then an "is" test is the way to go.
I'm just not sure why you would ever do that. Also, I'm not sure how
your assertion matches up with the examples; The examples test for
equality with a float that returns true for __eq__ and a Decimal that
returns false for __eq__. Both "1.0" and "Decimal(0, 1)" will return
False if the test is "is True" or "is False."

-Jack


== 3 of 4 ==
Date: Fri, Mar 5 2010 4:18 pm
From: Chris Rebert


On Fri, Mar 5, 2010 at 1:51 PM, Terry Reedy <tjreedy@udel.edu> wrote:
> On 3/5/2010 1:54 PM, Jean-Michel Pichavant wrote:
>> Steven D'Aprano wrote:
>
>> Despite there are good reasons for bool to be int, the newcomer 'wtf'
>> reaction at first glance is legitimate.
>> Starting python from scratch, booleans would have not been a subclass of
>> int (just guessing though), 'cause it makes no sense from a design POV.
>
> You are just guessing. I would argue for what we have. An example of its
> usefulness:
>
>>>> scores =[True, False, True, True, False]
>>>> score = sum(scores)
>>>> score
> 3
>
> Bools are also usefully used as sequence indexes.

Arguably, these sorts of uses only require bool to be /convertible/ to
int, not to necessarily be a /subclass/ of int.

Cheers,
Chris
--
http://blog.rebertia.com


== 4 of 4 ==
Date: Fri, Mar 5 2010 5:08 pm
From: Robert Kern


On 2010-03-05 17:48 PM, Jack Diederich wrote:
> On Fri, Mar 5, 2010 at 6:09 PM, Steven D'Aprano
> <steve@remove-this-cybersource.com.au> wrote:
>> On Fri, 05 Mar 2010 15:58:01 -0500, Jack Diederich wrote:
>>
>>>>> So, the pythonic way to check for True/False should be:
>>>>>
>>>>>>>> 1 is True
>>>>> False
>>>>
>>>> Why do you need to check for True/False?
>>>>
>>>>
>>> You should never check for "is" False/True but always check for
>>> equality. The reason is that many types support the equality (__eq__)
>>> and boolen (__bool__ in 3x) protocols. If you check equality these will
>>> be invoked, if you check identity ("is") they won't.
>>
>> Never say never.
>>
>> If you specifically want to test for True or False themselves, accepting
>> no substitutes, then using "is" is the obvious way, and using "==" is
>> clearly and obviously wrong because it does accept substitutes:
>>
>>>>> 1.0 == True
>> True
>>>>> decimal.Decimal(0, 1) == False
>> True
>
>
> Yes, obviously if you _really_ mean to test if something has the
> object identity of True or False then an "is" test is the way to go.
> I'm just not sure why you would ever do that. Also, I'm not sure how
> your assertion matches up with the examples; The examples test for
> equality with a float that returns true for __eq__ and a Decimal that
> returns false for __eq__.

No, both comparisons return True. Decimal(0,1) is equal in value to 0 (and thus
False). Comparing it to False using __eq__ returns True.

> Both "1.0" and "Decimal(0, 1)" will return
> False if the test is "is True" or "is False."

Yes. That is exactly what he is asserting.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco


==============================================================================
TOPIC: My four-yorkshireprogrammers contribution
http://groups.google.com/group/comp.lang.python/t/dea5c94f3d058e26?hl=en
==============================================================================

== 1 of 1 ==
Date: Fri, Mar 5 2010 5:19 pm
From: Gregory Ewing


MRAB wrote:

> By the standards of just a few years later, that's not so much a
> microcomputer as a nanocomputer!

Although not quite as nano as another design published
in EA a couple of years earlier, the EDUC-8:

http://www.sworld.com.au/steven/educ-8/

It had a *maximum* of 256 bytes -- due to the architecture,
there was no way of addressing any more. Also it was
divided into 16-byte pages, with indirect addressing
required to access anything in a different page from
the instruction. Programming for it must have been
rather challenging.

As far as I know, the EDUC-8 is unique in being the
only computer design ever published in a hobby magazine
that *wasn't* based on a microprocessor -- it was all
built out of 9000 and 7400 series TTL logic chips!

--
Greg

==============================================================================
TOPIC: best practices: is collections.defaultdict my friend or not?
http://groups.google.com/group/comp.lang.python/t/4bfdc60d3f58c960?hl=en
==============================================================================

== 1 of 6 ==
Date: Fri, Mar 5 2010 5:22 pm
From: Pete Emerson


I've been wrestling with dicts. I hope at the very least what I
discovered helps someone else out, but I'm interested in hearing from
more learned python users.

I found out that adding a two dimensional element without defining
first dimension existing doesn't work:

>>> data = {}
>>> data['one']['two'] = 'three'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'one'
>>> data['one'] = {}
>>> data['one']['two'] = 'three'
>>> print data
{'one': {'two': 'three'}}

And through some research, I discovered collections.defaultdict (new
in Python 2.5, FWIW):

>>> import collections
>>> data = collections.defaultdict(dict)
>>> data['one']['two'] = 'three'
>>> print data
defaultdict(<type 'dict'>, {'one': {'two': 'three'}})

Why isn't the behavior of collections.defaultdict the default for a
dict?
Am I just revelling in my bad perl habits by not wanting to declare a
previous level first?
Is this sort of "more rigid" way of doing things common throughout
python, and is it best that I not fight it, but embrace it?

Your thoughts and comments are very much appreciated. I think my brain
already knows some of the answers, but my heart ... well, perl and I
go way back. Loving python so far, though.

Pete


== 2 of 6 ==
Date: Fri, Mar 5 2010 6:02 pm
From: Andreas Waldenburger


On Fri, 5 Mar 2010 17:22:14 -0800 (PST) Pete Emerson
<pemerson@gmail.com> wrote:

> I've been wrestling with dicts. I hope at the very least what I
> discovered helps someone else out, but I'm interested in hearing from
> more learned python users.
>
> I found out that adding a two dimensional element without defining
> first dimension existing doesn't work:
>
> >>> data = {}
> >>> data['one']['two'] = 'three'
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> KeyError: 'one'
Yeah, because that key 'one' indexes what exactly?


> [snip]
>
> And through some research, I discovered collections.defaultdict (new
> in Python 2.5, FWIW):
>
> [snip]
>
> Why isn't the behavior of collections.defaultdict the default for a
> dict?
Because explicit is better than implicit. How should Python know what
you want to fill your dict with? It could be anything that takes string
indices. Only two lines of code remove all the guesswork.


> Am I just revelling in my bad perl habits by not wanting to declare a
> previous level first?
Yes.

Python pretty much never guesses (not that I knew of anyway). I think
that is good, because it's just too easy to overlook some magic the
language does and spend an hour trying to understand why that Toyota
hit that wall.


> Is this sort of "more rigid" way of doing things common throughout
> python, and is it best that I not fight it, but embrace it?
>
Seriously, what answer do you expect? ;) When has fighting a language
ever brought about something really cool. (I'm really looking forward
to the geeky humorous replies this is bound to sprout.)

> Your thoughts and comments are very much appreciated. I think my brain
> already knows some of the answers, but my heart ... well, perl and I
> go way back. Loving python so far, though.
>
Welcome on board.

Have you typed "import this" in the command prompt yet?

--
INVALID? DE!

== 3 of 6 ==
Date: Fri, Mar 5 2010 6:10 pm
From: Andreas Waldenburger


On Fri, 5 Mar 2010 17:22:14 -0800 (PST) Pete Emerson
<pemerson@gmail.com> wrote:

> [snip]
> >>> data['one'] = {}
> >>> data['one']['two'] = 'three'
> >>> print data
> {'one': {'two': 'three'}}
>
> And through some research, I discovered collections.defaultdict (new
> in Python 2.5, FWIW):
>
> >>> import collections
> >>> data = collections.defaultdict(dict)
> >>> data['one']['two'] = 'three'
> >>> print data
> defaultdict(<type 'dict'>, {'one': {'two': 'three'}})
>
> [snip]
> Your thoughts and comments are very much appreciated. I think my brain
> already knows some of the answers, but my heart ... well, perl and I
> go way back. Loving python so far, though.
>

Oh, by the way: That defaultdict route is a pretty solid solution. Not
sure what problem you're trying to solve -- depending on your usecase,
there might be a better approach.

If you're just asking hypothetically and you're trying to apply a
Perl idiom to Python, there probably *is* a better solution.

/W

--
INVALID? DE!

== 4 of 6 ==
Date: Fri, Mar 5 2010 6:26 pm
From: MRAB


Pete Emerson wrote:
> I've been wrestling with dicts. I hope at the very least what I
> discovered helps someone else out, but I'm interested in hearing from
> more learned python users.
>
> I found out that adding a two dimensional element without defining
> first dimension existing doesn't work:
>
>>>> data = {}
>>>> data['one']['two'] = 'three'
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> KeyError: 'one'
>>>> data['one'] = {}
>>>> data['one']['two'] = 'three'
>>>> print data
> {'one': {'two': 'three'}}
>
> And through some research, I discovered collections.defaultdict (new
> in Python 2.5, FWIW):
>
>>>> import collections
>>>> data = collections.defaultdict(dict)
>>>> data['one']['two'] = 'three'
>>>> print data
> defaultdict(<type 'dict'>, {'one': {'two': 'three'}})
>
> Why isn't the behavior of collections.defaultdict the default for a
> dict?
> Am I just revelling in my bad perl habits by not wanting to declare a
> previous level first?
> Is this sort of "more rigid" way of doing things common throughout
> python, and is it best that I not fight it, but embrace it?
>
> Your thoughts and comments are very much appreciated. I think my brain
> already knows some of the answers, but my heart ... well, perl and I
> go way back. Loving python so far, though.
>
Someone once wrote about a case where he was porting a frontend from
Perl to Python. It called a backend and parsed the result. Sometimes
converting one of the fields to a number would raise a ValueError
because it would contain "ERR" instead of a number, which Perl, of
course, would silently convert to 0!

Python is all about refusing to guess, and complaining if there's an
error. :-)


== 5 of 6 ==
Date: Fri, Mar 5 2010 6:30 pm
From: Pete Emerson


On Mar 5, 6:10 pm, Andreas Waldenburger <use...@geekmail.INVALID>
wrote:
> On Fri, 5 Mar 2010 17:22:14 -0800 (PST) Pete Emerson
>
>
>
>
>
> <pemer...@gmail.com> wrote:
> > [snip]
> > >>> data['one'] = {}
> > >>> data['one']['two'] = 'three'
> > >>> print data
> > {'one': {'two': 'three'}}
>
> > And through some research, I discovered collections.defaultdict (new
> > in Python 2.5, FWIW):
>
> > >>> import collections
> > >>> data = collections.defaultdict(dict)
> > >>> data['one']['two'] = 'three'
> > >>> print data
> > defaultdict(<type 'dict'>, {'one': {'two': 'three'}})
>
> > [snip]
> > Your thoughts and comments are very much appreciated. I think my brain
> > already knows some of the answers, but my heart ... well, perl and I
> > go way back. Loving python so far, though.
>
> Oh, by the way: That defaultdict route is a pretty solid solution. Not
> sure what problem you're trying to solve -- depending on your usecase,
> there might be a better approach.
>
> If you're just asking hypothetically and you're trying to apply a
> Perl idiom to Python, there probably *is* a better solution.
>
> /W
>
> --
> INVALID? DE!

I found out about the need to declare the higher level as I was
reading in a JSON struct into a dict and then adding a new entry at a
lower level. Mostly just proof of concept stuff as I'm learning
python. I'm not sure that the use of defaultdict is really warranted
for me anywhere just yet. Mostly, I don't want to convert my perl to
python, that seems very counterproductive. Thank you very much for
your insight.

I was a little frightened of doing "import this" ("Hey, kid, run rm -
rf / and see what happens!"), but did, and the words are wise. :)

Pete


== 6 of 6 ==
Date: Fri, Mar 5 2010 6:53 pm
From: Paul Rubin


Pete Emerson <pemerson@gmail.com> writes:
> I found out that adding a two dimensional element without defining
> first dimension existing doesn't work:
>
>>>> data = {}
>>>> data['one']['two'] = 'three'

You can use a tuple as a subscript if you want:

data = {}
data['one','two'] = 'three'

==============================================================================
TOPIC: A "scopeguard" for Python
http://groups.google.com/group/comp.lang.python/t/8c752e871801c223?hl=en
==============================================================================

== 1 of 1 ==
Date: Fri, Mar 5 2010 6:32 pm
From: "Alf P. Steinbach"


* Robert Kern:
> On 2010-03-03 09:39 AM, Mike Kent wrote:
>> What's the compelling use case for this vs. a simple try/finally?
>>
>> original_dir = os.getcwd()
>> try:
>> os.chdir(somewhere)
>> # Do other stuff
>> finally:
>> os.chdir(original_dir)
>> # Do other cleanup
>
> A custom-written context manager looks nicer and can be more readable.
>
> from contextlib import contextmanager
> import os
>
> @contextmanager
> def pushd(path):
> original_dir = os.getcwd()
> os.chdir(path)
> try:
> yield
> finally:
> os.chdir(original_dir)
>
>
> with pushd(somewhere):
> ...
>
>
> I don't think a general purpose ScopeGuard context manager has any such
> benefits over the try: finally:, though.

class pushd( Cleanup ):
def __init__( self, path ):
original_dir = os.getcwd()
os.chdir( path )
self._actions.append( lambda: os.chdir( original_dir ) )


Disclaimer: haven't tested this, but it just occurred to me that for such small
init/cleanup wrappers the Cleanup class provides a nice alternative to
@contextmanager, as above: fewer lines, and perhaps even more clear code. :-)


Cheers,

- Alf


==============================================================================

You received this message because you are subscribed to the Google Groups "comp.lang.python"
group.

To post to this group, visit http://groups.google.com/group/comp.lang.python?hl=en

To unsubscribe from this group, send email to comp.lang.python+unsubscribe@googlegroups.com

To change the way you get mail from this group, visit:
http://groups.google.com/group/comp.lang.python/subscribe?hl=en

To report abuse, send email explaining the problem to abuse@googlegroups.com

==============================================================================
Google Groups: http://groups.google.com/?hl=en

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home


Real Estate