Reputation: 1006
Let's say we have two sets:
t = {('b', 3), ('a', 2)}
r = {('b', 4), ('c', 6)}
I want a union on 1st element to result in
u = {('b', 3), ('a', 2), ('c', 6)}
if duplicate symbol is present in both place (example 'b' in the above) then the element of the first list should be retained. Thanks.
Upvotes: 2
Views: 1646
Reputation: 211
A little bit shorter version:
s = dict((*r, *t))
set(s.items())
Output:
{('a', 2), ('b', 3), ('c', 6)}
Upvotes: 2
Reputation: 6536
Here is my one-line style solution based on comprehensions:
t = {('b', 3), ('a', 2)}
r = {('b', 4), ('c', 6)}
result = {*t, *{i for i in r if i[0] not in {j[0] for j in t}}}
print(result) # {('b', 3), ('a', 2), ('c', 6)}
Using conversion to dictionary to eliminate the duplicates, you can also do that, which is a quite smart solution IMHO:
t = {('b', 3), ('a', 2)}
r = {('b', 4), ('c', 6)}
result = {(k,v) for k,v in dict((*r,*t)).items()}
print(result) # {('b', 3), ('a', 2), ('c', 6)}
Upvotes: 0
Reputation: 61930
An alternative using chain:
from itertools import chain
t = {('b', 3), ('a', 2)}
r = {('b', 4), ('c', 6)}
result = set({k: v for k, v in chain(r, t)}.items())
Output
{('b', 3), ('a', 2), ('c', 6)}
Upvotes: 0
Reputation: 29099
You can't do that with set intersecion. Two objects are either equal or they are not. Since your objects are tuples, (b, 3)
and (b, 4)
are not equal, and you don't get to change that.
The obvious way would be to create your own class and redefine equality, something like
class MyTuple:
def __init__(self, values):
self.values = values
def __eq__(self, other):
return self.values[0] == other[0]
and create sets of such objects.
Upvotes: 0
Reputation: 5668
for el in r:
if not el[0] in [x[0] for x in t]:
t.add(el)
t
{('a', 2), ('b', 3), ('c', 6)}
Upvotes: 1
Reputation: 59741
Just do:
t = {('b', 3), ('a', 2)}
r = {('b', 4), ('c', 6)}
d = dict(r)
d.update(t)
u = set(d.items())
print(u)
Output:
{('c', 6), ('a', 2), ('b', 3)}
Upvotes: 6