Google Groups unterstützt keine neuen Usenet-Beiträge oder ‑Abos mehr. Bisherige Inhalte sind weiterhin sichtbar.

dict comprehension

6 Aufrufe
Direkt zur ersten ungelesenen Nachricht

Daniel Fetchinson

ungelesen,
01.02.2008, 00:51:1201.02.08
an 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

ungelesen,
01.02.2008, 01:06:1601.02.08
an 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

ungelesen,
01.02.2008, 01:10:1401.02.08
an
"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

ungelesen,
01.02.2008, 01:10:0401.02.08
an 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

ungelesen,
01.02.2008, 01:13:5801.02.08
an

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

ungelesen,
01.02.2008, 01:14:4901.02.08
an 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

ungelesen,
01.02.2008, 01:18:3501.02.08
an 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

ungelesen,
01.02.2008, 01:21:0101.02.08
an 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

ungelesen,
01.02.2008, 02:13:3701.02.08
an
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

ungelesen,
01.02.2008, 03:19:1601.02.08
an

Why not just

D = dict(zip(keys,values))

??

-- Paul

bearoph...@lycos.com

ungelesen,
01.02.2008, 05:09:5501.02.08
an
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

ungelesen,
01.02.2008, 08:38:5901.02.08
an
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

ungelesen,
01.02.2008, 12:29:5401.02.08
an 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

ungelesen,
02.02.2008, 13:06:5402.02.08
an
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

ungelesen,
02.02.2008, 16:10:4602.02.08
an
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

ungelesen,
03.02.2008, 04:02:4703.02.08
an
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 neue Nachrichten