ashastral
ashastral

Reputation: 2848

Remove a given element from the other set in a dict of two sets

I have a dict, { "foo": set(["a", "b"]), "bar": set(["c", "d"]) }, and I'm given an element of one of the two sets and the name of the other set. I need to remove that element. How would I go about doing this? My best attempt so far is this:

keys = dict.keys()
if Element in dict[keys[0]].union(dict[keys[1]]):
  dict[keys[abs(keys.index(Other_Set) - 1)]].remove(Element)

This seems to be a bit excessive, though; is there any way I can improve it?

Upvotes: 2

Views: 834

Answers (7)

the wolf
the wolf

Reputation: 35552

This is a much more "pythonic" way:

>>> d = { "foo": set(["a", "b"]), "bar": set(["b", "c"]) }

>>> d['foo']-=d['bar']
>>> d
{'foo': set(['a']), 'bar': set(['c', 'b'])}

Of course d['foo'] could be d[hashable_key] with hashable_key having user input or what have you.

Recall that the operators - & ^ | on sets are overloaded to the respective mutating methods of:

a_set.difference_update(other_set) # also "-"
a_set.intersection_update(other_set) # also "&"
a_set.symmetric_difference_update(other_set) # also "^"
a_set.update(other_set) # also "-"

You can then use augmented assignment -= to modify the set value of 'foo' in place. All these other solutions offered here seem -- too wordy to me.

Edit I misread the OP, and ignore this as an answer. I voted up the best solution.

Upvotes: -1

Tony Veijalainen
Tony Veijalainen

Reputation: 5555

My variation, generic for any number of sets, takes out given item for all the others:

dict_of_sets={'foo':set(['a','b','c']),'bar': set(['d','b','e']),'onemore': set(['a','e','b'])}
givenset,givenitem='bar','b'
otherset= (key for key in dict_of_sets if key != givenset)
for setname in otherset:
  dict_of_sets[setname].discard(givenitem)

print dict_of_sets

"""Output:
{'foo': set(['c', 'a']), 'bar': set(['e', 'b', 'd']), 'onemore': set(['e', 'a'])}
"""

Upvotes: 0

unutbu
unutbu

Reputation: 880279

This one might suit you if you do not know a priori the names of the keys in dct:

dct={ "foo": set(["a", "b"]), "bar": set(["c", "d"]) }

element='b'
other_set='bar'

for key,value in dct.iteritems():
    if key != other_set:
        value.discard(element)

print(dct)
# {'foo': set(['a']), 'bar': set(['c', 'd'])}

Upvotes: 1

Vicki Laidler
Vicki Laidler

Reputation: 3489

Use a dictionary to look up the other set:

>>> other={'foo':'bar','bar':'foo'}
>>> d = { "foo": set(["a", "b"]), "bar": set(["b", "c"]) }
>>> element = "b"
>>> setname = "bar"
>>> d[other[setname]].discard(element)
>>> d
{'foo': set(['a']), 'bar': set(['c', 'b'])}

Upvotes: 2

carl
carl

Reputation: 50554

Try this:

dictionary['foo' if otherset == 'bar' else 'bar'].discard(element)

Upvotes: 3

Plumenator
Plumenator

Reputation: 1682

element = "b"
other = "bar"
d = { "foo": set(["a", "b"]), "bar": set(["b", "c"]) }
theSet = d[[s for s in d.iterkeys() if s != other][0]]
theSet.discard(element)

Upvotes: 0

Matthew Flaschen
Matthew Flaschen

Reputation: 284927

How about:

keys = dict.keys()
dict[keys[1 - keys.index(Other_Set)]].discard(Element)

With discard, you don't get a KeyError if the element's not in the set. Thus, you don't need your check (another alternative is to just ignore the KeyError). And 1 - removes the need for the abs.

Upvotes: 1

Related Questions