By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,799 Members | 1,376 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,799 IT Pros & Developers. It's quick & easy.

Dict Comprehension ?

P: n/a
Given 2 Number-Lists say l0 and l1,
count the various positiv differences between the 2 lists

the following part works:

dif=[abs(x-y) for x in l0 for y in l1]
da={}
for d in dif: da[d]=da.get(d,0)+1

i wonder, if there is a way, to avoid the list dif

Ernst-Ludwig Brust
Oct 6 '08 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Ernst-Ludwig Brust:
Given 2 Number-Lists say l0 and l1,
count the various positiv differences between the 2 lists
...
i wonder, if there is a way, to avoid the list dif
Instead of creating the list (array) dif, you can create a lazy
iterator. Then you can fed it to a set.

Bye,
bearophile
Oct 6 '08 #2

P: n/a
On Oct 6, 8:59 am, "Ernst-Ludwig Brust" <seinnix...@online.dewrote:
Given 2 Number-Lists say l0 and l1,
count the various positiv differences between the 2 lists

the following part works:

dif=[abs(x-y) for x in l0 for y in l1]
da={}
for d in dif: da[d]=da.get(d,0)+1

i wonder, if there is a way, to avoid the list dif

Ernst-Ludwig Brust
from collections import defaultdict
da=defaultdict(int)
for x in [10]:
for y in [11]:
da[abs(x-y)]+=1
Oct 6 '08 #3

P: n/a
"Ernst-Ludwig Brust" <se********@online.dewrites:
Given 2 Number-Lists say l0 and l1,
count the various positiv differences between the 2 lists

the following part works:

dif=[abs(x-y) for x in l0 for y in l1]
da={}
for d in dif: da[d]=da.get(d,0)+1

i wonder, if there is a way, to avoid the list dif
You can iterate over any iterable. A generator is iterable; and you
can (among other ways) create a generator with a generator
expression.

Fortunately, you already know how to write any generator expression:
it's the same as a list comprehension, but without the square
brackets.

So, instead of making a list of differences and iterating over it::
>>seq_a = [15, 17, 26]
seq_b = [14, 17, 22]
diffs = [abs(a - b) for a in seq_a for b in seq_b]
diff_accumulator = {}
for diff in diffs:
... diff_accumulator[diff] = diff_accumulator.get(diff, 0) + 1
...
>>diff_accumulator
{0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 7: 1, 9: 1, 12: 1}

you can skip the intermediate list creation and iterate over the
generator made by an identical generator expression::
>>seq_a = [15, 17, 26]
seq_b = [14, 17, 22]
diff_accumulator = {}
for diff in (abs(a - b) for a in seq_a for b in seq_b):
... diff_accumulator[diff] = diff_accumulator.get(diff, 0) + 1
...
>>diff_accumulator
{0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 7: 1, 9: 1, 12: 1}

If you wanted to avoid starting the dict empty and writing the ‘for’
loop yourself, you could even create your dict from a generator (the
dict type can make a new dict from any key+value iterable) with the
help of the standard library ‘itertools’ module::
>>import itertools
seq_a = [15, 17, 26]
seq_b = [14, 17, 22]
diffs = [abs(a - b) for a in seq_a for b in seq_b]
diff_accumulator = dict(
... (diff, len(list(items)))
... for (diff, items) in itertools.groupby(diffs)
... )
>>diff_accumulator
{0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 7: 1, 9: 1, 12: 1}

This also, of course, benefits from the earlier approach to iterate
over the diffs directly instead of an intermediate list::
>>import itertools
seq_a = [15, 17, 26]
seq_b = [14, 17, 22]
diff_accumulator = dict(
... (diff, len(list(items)))
... for (diff, items) in itertools.groupby(
... abs(a - b) for a in seq_a for b in seq_b
... )
... )
>>diff_accumulator
{0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 7: 1, 9: 1, 12: 1}

So, generator expressions can be a powerful way to clarify the purpose
of a section of code. They can be over-used, though: don't use them
unless they actually *do* clarify the code; sometimes an explicit
looping construct is clearer.

--
\ “Like the creators of sitcoms or junk food or package tours, |
`\ Java's designers were consciously designing a product for |
_o__) people not as smart as them.” —Paul Graham |
Ben Finney
Oct 7 '08 #4

P: n/a
<be************@lycos.comschrieb im Newsbeitrag
news:5b**********************************@m74g2000 hsh.googlegroups.com...
>
Instead of creating the list (array) dif, you can create a lazy
iterator. Then you can fed it to a set.
Thangs,
this idea is not only less storage-consuming but even faster
than the "List-Version".
But, i used the idea of pruebauno,
as this is faster.

Ernst-Ludwig Brust
Oct 7 '08 #5

P: n/a
"Ben Finney" <bi****************@benfinney.id.auschrieb im Newsbeitrag
news:87************@benfinney.id.au...
"Ernst-Ludwig Brust" <se********@online.dewrites:

So, generator expressions can be a powerful way to clarify the purpose
of a section of code. They can be over-used, though: don't use them
unless they actually *do* clarify the code; sometimes an explicit
looping construct is clearer.
Thangs,
my opinion was, that "one-statement-constructions" are
much faster then f.e. explicit loops.
But,
now i know, with Python, this is not allways true.

Ernst-Ludwig Brust
Oct 7 '08 #6

P: n/a
<pr*******@latinmail.comschrieb im Newsbeitrag
news:7c**********************************@75g2000h so.googlegroups.com...
>
from collections import defaultdict
da=defaultdict(int)
for x in [10]:
for y in [11]:
da[abs(x-y)]+=1
Thangs,
collections are a real good idea.
I will use this version.

Ernsst-Ludwwig Brust
Oct 7 '08 #7

This discussion thread is closed

Replies have been disabled for this discussion.