Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #33473 > unrolled thread

Re: Python Interview Questions

Started bychinjannisha@gmail.com
First post2012-11-17 10:01 -0800
Last post2012-11-19 07:02 +1100
Articles 4 on this page of 24 — 10 participants

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: Python Interview Questions chinjannisha@gmail.com - 2012-11-17 10:01 -0800
    Re: Python Interview Questions Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2012-11-18 01:54 -0500
    Re: Python Interview Questions Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-11-18 09:39 +0000
      Re: Python Interview Questions Roy Smith <roy@panix.com> - 2012-11-18 08:53 -0500
        Re: Python Interview Questions Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-11-18 16:50 +0000
          Re: Python Interview Questions "D'Arcy J.M. Cain" <darcy@druid.net> - 2012-11-18 12:16 -0500
          Re: Python Interview Questions Roy Smith <roy@panix.com> - 2012-11-18 12:53 -0500
            Re: Python Interview Questions Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-11-19 00:31 +0000
              Re: Python Interview Questions Roy Smith <roy@panix.com> - 2012-11-18 21:09 -0500
                Re: Python Interview Questions Chris Angelico <rosuav@gmail.com> - 2012-11-19 13:18 +1100
                Re: Python Interview Questions Mark Lawrence <breamoreboy@yahoo.co.uk> - 2012-11-19 02:42 +0000
                Re: Python Interview Questions Ian Kelly <ian.g.kelly@gmail.com> - 2012-11-18 23:01 -0700
                Re: Python Interview Questions Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-11-19 07:54 +0000
                  Re: Python Interview Questions Roy Smith <roy@panix.com> - 2012-11-19 09:30 -0500
                    Re: Python Interview Questions Ian Kelly <ian.g.kelly@gmail.com> - 2012-11-19 09:44 -0700
                    Re: Python Interview Questions Terry Reedy <tjreedy@udel.edu> - 2012-11-19 15:41 -0500
                    Re: Python Interview Questions Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-11-19 23:42 +0000
                      Re: Python Interview Questions Roy Smith <roy@panix.com> - 2012-11-19 21:33 -0500
                  Re: Python Interview Questions Roy Smith <roy@panix.com> - 2012-11-19 09:59 -0500
                    Re: Python Interview Questions Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-11-19 23:53 +0000
                      Re: Python Interview Questions Roy Smith <roy@panix.com> - 2012-11-19 22:14 -0500
                    RE: Python Interview Questions "Prasad, Ramit" <ramit.prasad@jpmorgan.com> - 2012-11-19 23:57 +0000
                Re: Python Interview Questions Terry Reedy <tjreedy@udel.edu> - 2012-11-19 03:27 -0500
          Re: Python Interview Questions Chris Angelico <rosuav@gmail.com> - 2012-11-19 07:02 +1100

Page 2 of 2 — ← Prev page 1 [2]


#33583

FromRoy Smith <roy@panix.com>
Date2012-11-19 22:14 -0500
Message-ID<roy-5B264E.22143919112012@news.panix.com>
In reply to#33567
In article <50aac66c$0$29983$c3e8da3$5496439d@news.astraweb.com>,
 Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote:

> I'm asking about the case where one might want the key to remain mutable 
> even after it is used as a key, but can't because Python won't let you.

Ah.  Now I see what you're getting at.  Thank you.

Well, I will admit that it probably doesn't make sense to mutate an 
object after it's put into a dict (or at least mutate it in a way which 
changes it's hash value and/or whether it compares equal to the original 
object).  If you did (assuming lists were allowed as keys):

l = [1, 2, 3]
d = {l: "spam"}
l.append(4)
print d[l]

I'm not sure what I would expect to print.  It's not too hard to 
experiment, though.  All you need do is:

class HashableList(list):
    def __hash__(self):
        return hash(tuple(self))

and python is then happy to let you use a list as a key.  I just played 
around with this a bit off-line.  I think I got the results I was 
expecting, but since I'm not sure what I was expecting, that's hard to 
say.

However, you didn't ask if it made sense to mutate an object after using 
it as a key.  You asked if it made sense to let the object remain 
mutable after using it as a key.  That's a harder question.

Let's say I had lots of of lists I wanted to use a dictionary keys.  As 
it stands now, I have to convert them to tuples, which means copying all 
the data.  For a lot of data, that's inefficient.

Wouldn't it be nice (or at least, more efficient) if I could just use 
the original lists as keys directly, without the extra copy?  I would 
have to understand that even though they are mutable, interesting (and 
perhaps, unwanted) things if I actually mutated them.  But, we're all 
consenting adults here.  If I'm willing to accept responsibility for the 
consequences of my actions in return for the efficiency gain, why 
shouldn't I be allowed to?

I guess the answer is, that I am allowed to.  I just need to do the 
HashableList deal, shown above (no broken URL required to read the code).

[toc] | [prev] | [next] | [standalone]


#33568

From"Prasad, Ramit" <ramit.prasad@jpmorgan.com>
Date2012-11-19 23:57 +0000
Message-ID<mailman.20.1353369510.29569.python-list@python.org>
In reply to#33541
Roy Smith wrote:
> 
> OK, I've just read back over the whole thread.  I'm really struggling to
> understand what point you're trying to make.  I started out by saying:
> 
> > Use a list when you need an ordered collection which is mutable (i.e.
> > can be altered after being created).  Use a tuple when you need an
> > immutable list (such as for a dictionary key).
> 
> To which you obviously objected.  So now you write:
> 
> > I think a tuple is an immutable sequence of items, and a list is a
> > mutable sequence of items.
> 
> So how is that different from what I said?  Is this whole argument
> boiling down to your use of "immutable sequence" vs. my use of
> "immutable list"?


'''
Roy:
> Use a list when you need an ordered collection which is mutable (i.e.
> can be altered after being created).  Use a tuple when you need an
> immutable list (such as for a dictionary key).
Steven:
I keep hearing about this last one, but I wonder... who *actually* does 
this? I've created many, many lists over the years -- lists of names, 
lists of phone numbers, lists of directory search paths, all sorts of 
things. I've never needed to use one as a dictionary key.
'''

To me this is more of a question than an argument. Now moving
on to your specific example.

'''
def extract_stack(lines):
    "in traceback_helper module "
    header = lines[0]
    stack = []
    for line in lines:
        m = frame_pattern.match(line)
        if not m:
            continue
        frame = (m.group('path'), m.group('function'))
        stack.append(frame)
    # [Convert to tuple and return after finished building stack.]
    return (header, stack)
[...]
def main(args):
    crashes = {}
    [...]
    for line in open(log_file):
        if does_not_look_like_a_stack_dump(line):
             continue
        lines = traceback_helper.unfold(line)
        header, stack = traceback_helper.extract_stack(lines)
        signature = tuple(stack)
        if signature in crashes:
            count, header = crashes[signature]
            crashes[signature] = (count + 1, header)
        else:

            crashes[signature] = (1, header)
'''

Seems to me that Steven is suggesting that stack (after being built)
should converted to a tuple before being returned, because a "stack" 
for any unique exception should be unique and immutable. You do this
anyway; you just do it before putting it into a dictionary rather
than before returning it.

Same net effect (as long as you do not modify `stack` later), so no 
real argument.


~Ramit


This email is confidential and subject to important disclaimers and
conditions including on offers for the purchase or sale of
securities, accuracy and completeness of information, viruses,
confidentiality, legal privilege, and legal entity disclaimers,
available at http://www.jpmorgan.com/pages/disclosures/email.  

[toc] | [prev] | [next] | [standalone]


#33535

FromTerry Reedy <tjreedy@udel.edu>
Date2012-11-19 03:27 -0500
Message-ID<mailman.0.1353313685.29569.python-list@python.org>
In reply to#33522
On 11/19/2012 1:01 AM, Ian Kelly wrote:

> than tuple access.  Tuples are as fast as or faster than lists, pretty
> much universally.  They seem to have closed the gap a bit in
> Python 3.3, though, as the following timings show.  For one-shot
> construction, tuples seem to be more efficient for short sequences,
> but then lists win for longer sequences, although not by much.  Of
> course, lists are always going to be much slower if you build them up
> with appends and extends.

Interesting results. But what system (hardware, os). These sorts of 
times tend to vary with the system.
>
> C:\>python -m timeit -s "x = range(10)" "tuple(x)"
> 1000000 loops, best of 3: 0.773 usec per loop
>
> C:\>python -m timeit -s "x = range(10)" "list(x)"
> 1000000 loops, best of 3: 0.879 usec per loop
>
> C:\>python -m timeit -s "x = range(100)" "tuple(x)"
> 100000 loops, best of 3: 2.88 usec per loop
>
> C:\>python -m timeit -s "x = range(100)" "list(x)"
> 100000 loops, best of 3: 2.63 usec per loop
>
> C:\>python -m timeit -s "x = range(1000)" "tuple(x)"
> 10000 loops, best of 3: 37.4 usec per loop
>
> C:\>python -m timeit -s "x = range(1000)" "list(x)"
> 10000 loops, best of 3: 36.2 usec per loop
>
> C:\>python -m timeit -s "x = range(10000)" "tuple(x)"
> 1000 loops, best of 3: 418 usec per loop
>
> C:\>python -m timeit -s "x = range(10000)" "list(x)"
> 1000 loops, best of 3: 410 usec per loop
>
>
> For iteration, tuples are consistently 7-8% faster.
>
>
> C:\>python -m timeit -s "x = tuple(range(10))" "for i in x: pass"
> 1000000 loops, best of 3: 0.467 usec per loop
>
> C:\>python -m timeit -s "x = list(range(10))" "for i in x: pass"
> 1000000 loops, best of 3: 0.498 usec per loop
>
> C:\>python -m timeit -s "x = tuple(range(100))" "for i in x: pass"
> 100000 loops, best of 3: 3.31 usec per loop
>
> C:\>python -m timeit -s "x = list(range(100))" "for i in x: pass"
> 100000 loops, best of 3: 3.56 usec per loop
>
> C:\>python -m timeit -s "x = tuple(range(1000))" "for i in x: pass"
> 10000 loops, best of 3: 31.6 usec per loop
>
> C:\>python -m timeit -s "x = list(range(1000))" "for i in x: pass"
> 10000 loops, best of 3: 34.3 usec per loop
>
> C:\>python -m timeit -s "x = tuple(range(10000))" "for i in x: pass"
> 1000 loops, best of 3: 318 usec per loop
>
> C:\>python -m timeit -s "x = list(range(10000))" "for i in x: pass"
> 1000 loops, best of 3: 341 usec per loop
>
>
> For direct item access, tuples seem to be about 2-3% faster.
>
>
> C:\>python -m timeit -s "import operator as o; x = tuple(range(10)); g
> = o.itemgetter(*range(len(x)))" "g(x)"
> 1000000 loops, best of 3: 0.67 usec per loop
>
> C:\>python -m timeit -s "import operator as o; x = list(range(10)); g
> = o.itemgetter(*range(len(x)))" "g(x)"
> 1000000 loops, best of 3: 0.674 usec per loop
>
> C:\>python -m timeit -s "import operator as o; x = tuple(range(100));
> g = o.itemgetter(*range(len(x)))" "g(x)"
> 100000 loops, best of 3: 4.52 usec per loop
>
> C:\>python -m timeit -s "import operator as o; x = list(range(100)); g
> = o.itemgetter(*range(len(x)))" "g(x)"
> 100000 loops, best of 3: 4.65 usec per loop
>
> C:\>python -m timeit -s "import operator as o; x = tuple(range(1000));
> g = o.itemgetter(*range(len(x)))" "g(x)"
> 10000 loops, best of 3: 43.2 usec per loop
>
> C:\>python -m timeit -s "import operator as o; x = list(range(1000));
> g = o.itemgetter(*range(len(x)))" "g(x)"
> 10000 loops, best of 3: 43.7 usec per loop
>
> C:\>python -m timeit -s "import operator as o; x =
> tuple(range(10000)); g = o.itemgetter(*range(len(x)))" "g(x)"
> 1000 loops, best of 3: 422 usec per loop
>
> C:\>python -m timeit -s "import operator as o; x = list(range(10000));
> g = o.itemgetter(*range(len(x)))" "g(x)"
> 1000 loops, best of 3: 447 usec per loop
>


-- 
Terry Jan Reedy

[toc] | [prev] | [next] | [standalone]


#33512

FromChris Angelico <rosuav@gmail.com>
Date2012-11-19 07:02 +1100
Message-ID<mailman.3799.1353268978.27098.python-list@python.org>
In reply to#33507
On Mon, Nov 19, 2012 at 4:16 AM, D'Arcy J.M. Cain <darcy@druid.net> wrote:
> On 18 Nov 2012 16:50:52 GMT
> Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote:
>> On Sun, 18 Nov 2012 08:53:25 -0500, Roy Smith wrote:
>>> > Use a list when you need an ordered collection which is mutable
>> > (i.e. can be altered after being created).  Use a tuple when you
>> > need an immutable list (such as for a dictionary key).
>>
>> I keep hearing about this last one, but I wonder... who *actually*
>> does this? I've created many, many lists over the years -- lists of
>> names, lists of phone numbers, lists of directory search paths, all
>> sorts of things. I've never needed to use one as a dictionary key.
>
> Well, as long as *you* never needed it then...
>
> CellBlock = 9 # There's a riot going on...
> Cell = 17
> Bunk = "top"
>
> Prisoner = {(CellBlock, Cell, Bunk): "Bernie Madoff"}

That's a structure, not a list. Every key will consist of precisely
three values: two integers and one keyword string. Already covered by
a previous example.

ChrisA

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | comp.lang.python


csiph-web