Google Grupper har inte längre stöd för nya Usenet-inlägg eller -prenumerationer. Historiskt innehåll förblir synligt.
Dismiss

dict comprehension

6 visningar
Hoppa till det första olästa meddelandet

Daniel Fetchinson

oläst,
1 feb. 2008 00:51:122008-02-01
till pytho...@python.org
Hi folks,

There is a withdrawn PEP about a new syntax for dict comprehension:
http://www.python.org/dev/peps/pep-0274/ which says:

"Substantially all of its benefits were subsumed by generator
expressions coupled with the dict() constructor."

What does the author mean here? What's the Preferably One Way (TM) to
do something analogous to a dict comprehension?

Ryan Ginstrom

oläst,
1 feb. 2008 01:06:162008-02-01
till pytho...@python.org
> On Behalf Of Daniel Fetchinson

> What does the author mean here? What's the Preferably One Way
> (TM) to do something analogous to a dict comprehension?

I imagine something like this:

>>> keys = "a b c".split()
>>> values = [1, 2, 3]
>>> D = dict([(a, b) for a, b in zip(keys, values)])
>>> D
{'a': 1, 'c': 3, 'b': 2}

Regards,
Ryan Ginstrom

Paul Rubin

oläst,
1 feb. 2008 01:10:142008-02-01
till
"Daniel Fetchinson" <fetch...@googlemail.com> writes:
> What does the author mean here? What's the Preferably One Way (TM) to
> do something analogous to a dict comprehension?

from itertools import izip
d = dict((k,v) for k,v in izip(keys, values))

Gary Herron

oläst,
1 feb. 2008 01:10:042008-02-01
till Daniel Fetchinson, pytho...@python.org
Daniel Fetchinson wrote:
> Hi folks,
>
> There is a withdrawn PEP about a new syntax for dict comprehension:
> http://www.python.org/dev/peps/pep-0274/ which says:
>
> "Substantially all of its benefits were subsumed by generator
> expressions coupled with the dict() constructor."
>
> What does the author mean here? What's the Preferably One Way (TM) to
> do something analogous to a dict comprehension?
>
See about generator expressions in
http://www.python.org/doc/2.4/whatsnew/node4.html.

The dict builtin can build a dictionary from a list (or iterator or
generator creating a list) of tuples. Put them together and get what
you might be tempted to call a dictionary comprehension. For instance:

>>> dict((i,i*i) for i in range(10))
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

Gary Herron


Paddy

oläst,
1 feb. 2008 01:13:582008-02-01
till

Hi Ryan, that uses a list comprehension.
The generator comprehension is:
D = dict((a, b) for a, b in zip(keys, values))

(No square brackets)

- Paddy.

Gary Herron

oläst,
1 feb. 2008 01:14:492008-02-01
till Ryan Ginstrom, pytho...@python.org
Ryan Ginstrom wrote:
>> On Behalf Of Daniel Fetchinson
>> What does the author mean here? What's the Preferably One Way
>> (TM) to do something analogous to a dict comprehension?
>>
>
> I imagine something like this:
>
>
>>>> keys = "a b c".split()
>>>> values = [1, 2, 3]
>>>> D = dict([(a, b) for a, b in zip(keys, values)])
>>>> D
>>>>
> {'a': 1, 'c': 3, 'b': 2}
>
> Regards,
> Ryan Ginstrom
>
>
This fine example uses list comprehension to build a list of tuples
which is than read by the dict builtin to create a dictionary. You can
dispense with the intermediate list if you use a generator expression
directly as input to the dict builtin. (Requires Python 2.4 or later.)
Like this:

>>> keys = "a b c".split()
>>> values = [1, 2, 3]

>>> D = dict((a, b) for a, b in zip(keys, values))

Daniel Fetchinson

oläst,
1 feb. 2008 01:18:352008-02-01
till pytho...@python.org
> > Hi folks,
> >
> > There is a withdrawn PEP about a new syntax for dict comprehension:
> > http://www.python.org/dev/peps/pep-0274/ which says:
> >
> > "Substantially all of its benefits were subsumed by generator
> > expressions coupled with the dict() constructor."
> >
> > What does the author mean here? What's the Preferably One Way (TM) to
> > do something analogous to a dict comprehension?
> >
> See about generator expressions in
> http://www.python.org/doc/2.4/whatsnew/node4.html.
>
> The dict builtin can build a dictionary from a list (or iterator or
> generator creating a list) of tuples. Put them together and get what
> you might be tempted to call a dictionary comprehension. For instance:
>
> >>> dict((i,i*i) for i in range(10))
> {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

Neat!

Terry Reedy

oläst,
1 feb. 2008 01:21:012008-02-01
till pytho...@python.org

"Daniel Fetchinson" <fetch...@googlemail.com> wrote in message
news:fbe2e2100801312151x713...@mail.gmail.com...

| Hi folks,
|
| There is a withdrawn PEP about a new syntax for dict comprehension:
| http://www.python.org/dev/peps/pep-0274/ which says:

I believe both set and dict comprehensions will be in 3.0.

Arnaud Delobelle

oläst,
1 feb. 2008 02:13:372008-02-01
till
On Feb 1, 6:21 am, "Terry Reedy" <tjre...@udel.edu> wrote:
> "Daniel Fetchinson" <fetchin...@googlemail.com> wrote in message

>
> news:fbe2e2100801312151x713...@mail.gmail.com...
> | Hi folks,
> |
> | There is a withdrawn PEP about a new syntax for dict comprehension:
> |http://www.python.org/dev/peps/pep-0274/which says:
>
> I believe both set and dict comprehensions will be in 3.0.

Python 3.0a1+ (py3k:59330, Dec 4 2007, 18:44:39)
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> {x*x for x in range(10)}
{0, 1, 4, 81, 64, 9, 16, 49, 25, 36}
>>> {x:x*x for x in range(10)}


{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
>>>

That's nice.

--
Arnaud

Paul McGuire

oläst,
1 feb. 2008 03:19:162008-02-01
till

Why not just

D = dict(zip(keys,values))

??

-- Paul

bearoph...@lycos.com

oläst,
1 feb. 2008 05:09:552008-02-01
till
Paul McGuire:

> Why not just
> D = dict(zip(keys,values))
> ??

Because this may require less memory:

from itertools import izip
D = dict(izip(keys, values))

:-)

Bear hugs,
bearophile

Wildemar Wildenburger

oläst,
1 feb. 2008 08:38:592008-02-01
till
Arnaud Delobelle wrote:
>> I believe both set and dict comprehensions will be in 3.0.
>
> Python 3.0a1+ (py3k:59330, Dec 4 2007, 18:44:39)
> [GCC 4.0.1 (Apple Inc. build 5465)] on darwin
> Type "help", "copyright", "credits" or "license" for more information.
>>>> {x*x for x in range(10)}
> {0, 1, 4, 81, 64, 9, 16, 49, 25, 36}
>>>> {x:x*x for x in range(10)}
> {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
>
OK, not bad. But I don't really see how this is better than the
generator approach.

Also, what is that first thing? A valueless dict (and thus a set)?

/W

Stefan Behnel

oläst,
1 feb. 2008 12:29:542008-02-01
till Wildemar Wildenburger
Wildemar Wildenburger wrote:
> Arnaud Delobelle wrote:
>>> I believe both set and dict comprehensions will be in 3.0.
>>
>> Python 3.0a1+ (py3k:59330, Dec 4 2007, 18:44:39)
>> [GCC 4.0.1 (Apple Inc. build 5465)] on darwin
>> Type "help", "copyright", "credits" or "license" for more information.
>>>>> {x*x for x in range(10)}
>> {0, 1, 4, 81, 64, 9, 16, 49, 25, 36}
>>>>> {x:x*x for x in range(10)}
>> {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
>>
> OK, not bad. But I don't really see how this is better than the
> generator approach.

It's a literal syntax, just like you would do with a list, i.e. a list
comprehension. Why should you have list comps and no dict comps?


> Also, what is that first thing? A valueless dict (and thus a set)?

It's the literal set syntax added in 3.0. You can write

{1,2,3}

to get a set() or

{1:1,2:2}

to get a dict().

Stefan

Steven Bethard

oläst,
2 feb. 2008 13:06:542008-02-02
till
Wildemar Wildenburger wrote:
> Arnaud Delobelle wrote:
>>> I believe both set and dict comprehensions will be in 3.0.
>>
>> Python 3.0a1+ (py3k:59330, Dec 4 2007, 18:44:39)
>> [GCC 4.0.1 (Apple Inc. build 5465)] on darwin
>> Type "help", "copyright", "credits" or "license" for more information.
>>>>> {x*x for x in range(10)}
>> {0, 1, 4, 81, 64, 9, 16, 49, 25, 36}
>>>>> {x:x*x for x in range(10)}
>> {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
>>
> OK, not bad. But I don't really see how this is better than the
> generator approach.

It's more than twice as fast:

>>> setup = "items = range(10)"
>>> timeit.Timer("dict((x, x * x) for x in items)", setup).timeit()
6.0559464959932114
>>> timeit.Timer("{x:x * x for x in items}", setup).timeit()
2.8347301821879682

It also doesn't build the unnecessary intermediate tuples:

>>> def dict_genexp(items):
... return dict((x, x * x) for x in items)
...
>>> def dict_comp(items):
... return {x:x * x for x in items}
...
>>> dis.dis(dict_genexp.__code__.co_consts[1])
2 0 LOAD_FAST 0 (.0)
>> 3 FOR_ITER 21 (to 27)
6 STORE_FAST 1 (x)
9 LOAD_FAST 1 (x)
12 LOAD_FAST 1 (x)
15 LOAD_FAST 1 (x)
18 BINARY_MULTIPLY
19 BUILD_TUPLE 2
22 YIELD_VALUE
23 POP_TOP
24 JUMP_ABSOLUTE 3
>> 27 LOAD_CONST 0 (None)
30 RETURN_VALUE
>>> dis.dis(dict_comp.__code__.co_consts[1])
2 0 BUILD_MAP 0
3 DUP_TOP
4 STORE_FAST 1 (_[1])
7 LOAD_FAST 0 (.0)
>> 10 FOR_ITER 21 (to 34)
13 STORE_FAST 2 (x)
16 LOAD_FAST 1 (_[1])
19 LOAD_FAST 2 (x)
22 LOAD_FAST 2 (x)
25 BINARY_MULTIPLY
26 ROT_TWO
27 LOAD_FAST 2 (x)
30 STORE_SUBSCR
31 JUMP_ABSOLUTE 10
>> 34 RETURN_VALUE

STeVe

bearoph...@lycos.com

oläst,
2 feb. 2008 16:10:462008-02-02
till
Steven Bethard:

> It also doesn't build the unnecessary intermediate tuples:

I see, but can't the interpreter improved to remove similar
intermediate tuples anyway? Is this a difficult thing to do?

Bye,
bearophile

Arnaud Delobelle

oläst,
3 feb. 2008 04:02:472008-02-03
till
On Feb 2, 9:10 pm, bearophileH...@lycos.com wrote:
> Steven Bethard:
>
> > It also doesn't build the unnecessary intermediate tuples:
>
> I see, but can't the interpreter improved to remove similar
> intermediate tuples anyway?

Do you mean the compiler?

> Is this a difficult thing to do?

Yes, due to the HDNP (Highly Dynamic Nature of Python).

--
Arnaud

0 nya meddelanden