Want to reduce steps of an operation with dictionaries

P

pretoriano_2001

Hello:
I have next dictionaries:
a={'a':0, 'b':1, 'c':2, 'd':3}
b={'a':0, 'c':1, 'd':2, 'e':3}
I want to put in a new dictionary named c all the keys that are in b
and re-sequence the values. The result I want is:
c={'a':0, 'c':1, 'd':2}
How can I do this with one line of instruction?

I attempted the next but the output is not the expected:
c=dict([(k,v) for v,k in enumerate(a) if b.has_key(k)])
erroneously (for me) gets:
{'a': 0, 'c': 2, 'd': 3}

Thanks for your help.
 
S

Steve Holden

Hello:
I have next dictionaries:
a={'a':0, 'b':1, 'c':2, 'd':3}
b={'a':0, 'c':1, 'd':2, 'e':3}
I want to put in a new dictionary named c all the keys that are in b
and re-sequence the values. The result I want is:
c={'a':0, 'c':1, 'd':2}
How can I do this with one line of instruction?
You can't. Dictionaries aren't ordered collections.
I attempted the next but the output is not the expected:
c=dict([(k,v) for v,k in enumerate(a) if b.has_key(k)])
erroneously (for me) gets:
{'a': 0, 'c': 2, 'd': 3}

Thanks for your help.
In Python {'a':0, 'c':1, 'd':2} == {'a': 0, 'c': 2, 'd': 3}

Sounds like you want an ordered dictionary. Several people have
implemented such a beast, but I have never felt the need for one.

Alternatively, perhaps the ordering of the elements isn't really important.

regards
Steve
 
B

Ben Finney

I have next dictionaries:
a={'a':0, 'b':1, 'c':2, 'd':3}
b={'a':0, 'c':1, 'd':2, 'e':3}
I want to put in a new dictionary named c all the keys that are in b
and re-sequence the values.

They never had a sequence, so you can't "re-sequence" them.

You have not, perhaps, worked your way through the Python
tutorial. It's quite comprehensive and will give you a good grounding
in the basic concepts.

<URL:http://docs.python.org/tut/>
 
G

Gabriel Genellina

At said:
a={'a':0, 'b':1, 'c':2, 'd':3}
b={'a':0, 'c':1, 'd':2, 'e':3}
I want to put in a new dictionary named c all the keys that are in b
and re-sequence the values. The result I want is:
c={'a':0, 'c':1, 'd':2}
How can I do this with one line of instruction?

Why "one line"? Choosing the right data structure is far more
important than squeezing the code to fit on one single line.

I'm not sure if I understand you correctly - or maybe you're
confusing yourself.
If you're going to "re-sequence" the values, the original values are
not relevant at all; so maybe you need a list instead of a dict.

Perhaps this is what you want (something like swapping keys<->values):

a = ['a', 'b', 'c', 'd']
b = ['a', 'c', 'd', 'e']
c = [x for x in a if x in b]
c == ['a', 'c', 'd']
c[0] == 'a'
c[1] == 'c'
c[2] == 'd'


--
Gabriel Genellina
Softlab SRL

__________________________________________________
Correo Yahoo!
Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
 
C

Carl Banks

Hello:
I have next dictionaries:
a={'a':0, 'b':1, 'c':2, 'd':3}
b={'a':0, 'c':1, 'd':2, 'e':3}
I want to put in a new dictionary named c all the keys that are in b
and re-sequence the values. The result I want is:
c={'a':0, 'c':1, 'd':2}
How can I do this with one line of instruction?

I attempted the next but the output is not the expected:
c=dict([(k,v) for v,k in enumerate(a) if b.has_key(k)])
erroneously (for me) gets:
{'a': 0, 'c': 2, 'd': 3}

Filter first, Sort second, Enumerate third, Build Dict last:

c = dict((k,v) for (v,k) in enumerate(sorted(j for j in a if j in b)))


The inner generator you could do with sets also.

c = dict((k,v) for (v,k) in enumerate(sorted(set(a)&set(b))))


Carl Banks
 
J

James Stroud

Hello:
I have next dictionaries:
a={'a':0, 'b':1, 'c':2, 'd':3}
b={'a':0, 'c':1, 'd':2, 'e':3}
I want to put in a new dictionary named c all the keys that are in b
and re-sequence the values. The result I want is:
c={'a':0, 'c':1, 'd':2}
How can I do this with one line of instruction?

I attempted the next but the output is not the expected:
c=dict([(k,v) for v,k in enumerate(a) if b.has_key(k)])
erroneously (for me) gets:
{'a': 0, 'c': 2, 'd': 3}

Thanks for your help.
I think you have the right idea if I understand what you want:

c = dict(((k,v) for (v,k) in enumerate(x for x in a if b.has_key(x))))

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
C

Carl Banks

Steve said:
Hello:
I have next dictionaries:
a={'a':0, 'b':1, 'c':2, 'd':3}
b={'a':0, 'c':1, 'd':2, 'e':3}
I want to put in a new dictionary named c all the keys that are in b
and re-sequence the values. The result I want is:
c={'a':0, 'c':1, 'd':2}
How can I do this with one line of instruction?
You can't. Dictionaries aren't ordered collections.
I attempted the next but the output is not the expected:
c=dict([(k,v) for v,k in enumerate(a) if b.has_key(k)])
erroneously (for me) gets:
{'a': 0, 'c': 2, 'd': 3}

Thanks for your help.

In Python {'a':0, 'c':1, 'd':2} == {'a': 0, 'c': 2, 'd': 3}

Careful there, chief. The Python interpreter disagrees:
False

I inferred that by "re-sequencing", the OP meant the keys in the new
dict were to be associated with a new range of integer values (probably
specifically the key's index in a sorted list of keys). It was an
unfortunate choice of words, as sequencing has a pretty specific
meaning in Python.


Carl Banks
 
J

James Stroud

Ben said:
They never had a sequence, so you can't "re-sequence" them.

You have not, perhaps, worked your way through the Python
tutorial. It's quite comprehensive and will give you a good grounding
in the basic concepts.

<URL:http://docs.python.org/tut/>

The values in the example are sequentially ordered wrt the keys, which
is perhaps what the OP intends.


c = dict(((k,v) for (v,k) in enumerate(x for x in sorted(a.keys()) if
b.has_key(x))))

But, yes, there is decided ambiguity in his description of the problem.

James

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
M

Mike Erickson

Hello:
I have next dictionaries:
a={'a':0, 'b':1, 'c':2, 'd':3}
b={'a':0, 'c':1, 'd':2, 'e':3}
I want to put in a new dictionary named c all the keys that are in b
and re-sequence the values. The result I want is:
c={'a':0, 'c':1, 'd':2}
How can I do this with one line of instruction?

I attempted the next but the output is not the expected:
c=dict([(k,v) for v,k in enumerate(a) if b.has_key(k)])
erroneously (for me) gets:
{'a': 0, 'c': 2, 'd': 3}

I am not 100% I understand your questions, but k,v are being pulled from
a, try:

c=dict([(k,b[k]) for v,k in enumerate(a) if b.has_key(k)])

mike
 
S

Steve Holden

Carl said:
Steve said:
Hello:
I have next dictionaries:
a={'a':0, 'b':1, 'c':2, 'd':3}
b={'a':0, 'c':1, 'd':2, 'e':3}
I want to put in a new dictionary named c all the keys that are in b
and re-sequence the values. The result I want is:
c={'a':0, 'c':1, 'd':2}
How can I do this with one line of instruction?

You can't. Dictionaries aren't ordered collections.

I attempted the next but the output is not the expected:
c=dict([(k,v) for v,k in enumerate(a) if b.has_key(k)])
erroneously (for me) gets:
{'a': 0, 'c': 2, 'd': 3}

Thanks for your help.

In Python {'a':0, 'c':1, 'd':2} == {'a': 0, 'c': 2, 'd': 3}


Careful there, chief. The Python interpreter disagrees:


False

I inferred that by "re-sequencing", the OP meant the keys in the new
dict were to be associated with a new range of integer values (probably
specifically the key's index in a sorted list of keys). It was an
unfortunate choice of words, as sequencing has a pretty specific
meaning in Python.
Thanks: my bad.

regards
Steve
 
B

Ben Finney

I have next dictionaries:
a={'a':0, 'b':1, 'c':2, 'd':3}
b={'a':0, 'c':1, 'd':2, 'e':3}
I want to put in a new dictionary named c all the keys that are in b
and re-sequence the values. The result I want is:
c={'a':0, 'c':1, 'd':2}

Okay, it seems that what you mean isn't what most of us understand by
"re-sequence". I'm not sure what transformation you want to occur.

The result you specify doesn't match your description, "a new
dictionary named c all the keys that are in b and re-sequence the
values", because the result you show doesn't have "all the keys that
are in b".

This gets a dictionary with the keys you want:
>>> a = {'a':0, 'b':1, 'c':2, 'd':3}
>>> b = {'a':0, 'c':1, 'd':2, 'e':3}
>>> c = dict([(k,None) ... for k in a if k in b])
>>> print c
{'a': None, 'c': None, 'd': None}

though I don't understand what values you want in the dict.
How can I do this with one line of instruction?

Why one line?

As a general piece of advice, try writing dumb, obvious code that
actually does the transformation you want, and then let us see
that. Don't try to compress things into fewer lines unless that
actually makes it clearer to read.
I attempted the next but the output is not the expected:
c=dict([(k,v) for v,k in enumerate(a) if b.has_key(k)])

"if b.has_key(k)" can be replaced with "if k in b", as above.
erroneously (for me) gets:
{'a': 0, 'c': 2, 'd': 3}

Perhaps if you could write it as a series of for loops, or some other
more obvious algorithm, we could understand what you actually want.
 
F

Fredrik Lundh

Ben said:
Why one line?

As a general piece of advice, try writing dumb, obvious code that
actually does the transformation you want, and then let us see
that. Don't try to compress things into fewer lines unless that
actually makes it clearer to read.

I was about to suggest adding something along these lines to "import
this", but then I realized that it had to be written on one line to
fit into that module, so I dropped the idea.

</F>
 
B

Ben Finney

Fredrik Lundh said:
Ben said:
How can I do this with one line of instruction?

As a general piece of advice, [...] Don't try to compress things
into fewer lines unless that actually makes it clearer to read.

I was about to suggest adding something along these lines to "import
this", but then I realized that it had to be written on one line to
fit into that module, so I dropped the idea.

How about:

Lines of code are not a scarce resource; use as many as you need.
 
P

pretoriano_2001

James:
Your solution works for me, many, many thanks for your help and many
thanks for the time, teaching and reflections I received from all the
guys that participated in this thread.


James said:
Hello:
I have next dictionaries:
a={'a':0, 'b':1, 'c':2, 'd':3}
b={'a':0, 'c':1, 'd':2, 'e':3}
I want to put in a new dictionary named c all the keys that are in b
and re-sequence the values. The result I want is:
c={'a':0, 'c':1, 'd':2}
How can I do this with one line of instruction?

I attempted the next but the output is not the expected:
c=dict([(k,v) for v,k in enumerate(a) if b.has_key(k)])
erroneously (for me) gets:
{'a': 0, 'c': 2, 'd': 3}

Thanks for your help.
I think you have the right idea if I understand what you want:

c = dict(((k,v) for (v,k) in enumerate(x for x in a if b.has_key(x))))

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
P

pretoriano_2001

Mike:
Many thanks for your solution. It looks really nice.



Mike said:
Hello:
I have next dictionaries:
a={'a':0, 'b':1, 'c':2, 'd':3}
b={'a':0, 'c':1, 'd':2, 'e':3}
I want to put in a new dictionary named c all the keys that are in b
and re-sequence the values. The result I want is:
c={'a':0, 'c':1, 'd':2}
How can I do this with one line of instruction?

I attempted the next but the output is not the expected:
c=dict([(k,v) for v,k in enumerate(a) if b.has_key(k)])
erroneously (for me) gets:
{'a': 0, 'c': 2, 'd': 3}

I am not 100% I understand your questions, but k,v are being pulled from
a, try:

c=dict([(k,b[k]) for v,k in enumerate(a) if b.has_key(k)])

mike
 
M

Michael Naunton

It does not look nice at all, mainly because you are asking either asking the
question upside down, or not providing enough information.

If a and b are of vastly different sizes, say so. Otherwise, think about your
algorithm, and realize you are asking for things in b if they exist in a:
dict( [ i for i in b.items() if i[0] in a ] )
{'a': 0, 'c': 1, 'd': 2}

- another mike.

Mike:
Many thanks for your solution. It looks really nice.



Mike said:
Hello:
I have next dictionaries:
a={'a':0, 'b':1, 'c':2, 'd':3}
b={'a':0, 'c':1, 'd':2, 'e':3}
I want to put in a new dictionary named c all the keys that are in b
and re-sequence the values. The result I want is:
c={'a':0, 'c':1, 'd':2}
How can I do this with one line of instruction?

I attempted the next but the output is not the expected:
c=dict([(k,v) for v,k in enumerate(a) if b.has_key(k)])
erroneously (for me) gets:
{'a': 0, 'c': 2, 'd': 3}

I am not 100% I understand your questions, but k,v are being pulled from
a, try:

c=dict([(k,b[k]) for v,k in enumerate(a) if b.has_key(k)])

mike
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,162
Latest member
GertrudeMa
Top