Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
combining 2 dictionaries
#1
i have 2 dictionary expressions. i want to combine them into one so that the one has each item from both. if one is already in a variable i can use .update() on that variable. but both dictionaries are expressions that are comprehensions. if the | operator could be used for dictionaries like it can for sets then i could do something like:
(warning: invalid code)
fun( {foo(x):x for x in range(256)} | {bar(x):x for x in range(256)} )
but i am unable to come up with a way to do this without forming the dictionary in another variable using more than one line of code. i want to have it all in one comprehension.

IMHO: every operation for sets should be allowed on dictionary keys and work the same way.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#2
What version are you on? This works in 3.9. Prior to that you can use a different syntax.

def double(x):
    return 2 * x

def triple(x):
    return 3 * x

print({**{double(x):x for x in range(10)}, **{triple(x):x for x in range(10)}})
# works on 3.9+
print({double(x):x for x in range(10)} | {triple(x):x for x in range(10)})
The PEP that added this to dicts in 3.9 only added union. There is a section in the link that talks about the other set operators, but they were not added at the same time.
Reply
#3
does not work in 3.6.

the engine logic for this should be the same for sets and dictionaries. that's what i did in my C libraries (not the language i was building long long ago). the C stuff i did was a library for C that implemented a namespace that only used byte string for keys. but it had a no-value assigned capability, somewhat like how None gets used in Python. the C stuff just didn't implement a bunch of types. these were mappings. to create a node you call an add function with just a key. then you call an assign function with the value. it assigned to the last referenced node. you could do a lookup with a key and that was the last reference. if the lookup failed, the last reference was empty and assign would fail. it had other features like forward/reverse stepping (a way to iterate over the mapping).

one of these days, i will look and see how CPython does dictionaries and sets. if Python didn't have sets, i'd just use dictionaries for that.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#4
(Oct-26-2021, 10:46 PM)Skaperen Wrote: does not work in 3.6.

If you're referring to the syntax that I pointed out only works in 3.9 and later, I'd expect that. If you're referring to the other syntax, it works fine for me on 3.6.13.
Reply
#5
other? which is which?
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#6
print({**{double(x):x for x in range(10)}, **{triple(x):x for x in range(10)}})
# works on 3.9+
print({double(x):x for x in range(10)} | {triple(x):x for x in range(10)})
The line on the bottom (under the "works on 3.9+") only works on 3.9 and later.

The line on top works on (I think) 3.5 and later. The oldest I have right now is 3.6.13 and it works on that one.
Reply
#7
OK, yes, that works on 3.6.9.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Combining Dictionaries w/o overwriting MC2020 3 1,891 Apr-12-2020, 02:51 AM
Last Post: bowlofred

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020