I would like to know if there are any python functions that implement set()
with a key
argument, analogous to e.g. the key
in sorted(iterable, *, key=None, reverse=False)
?
I think this feature would be useful for certain cases, especially when comparing custom objects without having to change its hash()
function.
Example 1
iterable = [1.0, 1.5, 2.0, 2.5]
x = set(iterable) # yields {1.0, 1.5, 2.0, 2.5}
y = set(iterable, key=math.floor) # yields {1.0, 2.0}
Example 2
iterable = ['abc', 'ade', 'bbc', 'abc', 'bfg']
x = set(iterable) # yields {'abc', 'ade', 'bbc', 'bfg'}
y = set(iterable, key=lambda x: x[0]) # yields {'abc', 'bbc'}
I could imagine that this would not be implemented due to the difficulty of choosing which object is selected if a duplicate is found. However, this could be overcome by some strategy, e.g. 'choose first', 'choose random', 'choose last'.
Thank you for all of your responses, the most elegant solution for this problem was suggested by Daniel Roseman:
key = math.floor # Or any desired key function
y = set({key(i): i for i in iterable}.values())
Isn't that basically a dictionary, where the key is the result of applying the function to the value?
y = {math.floor(i): i for i in iterable}
You would implement that the other way around, with a custom type:
class FlooredFloat:
def __init__(self, value):
self.value = value
def __hash__(self):
return hash(math.floor(self.value))
def __eq__(self, other):
return other.value == self.value
iterable = [1.0, 1.5, 2.0, 2.5]
x = set(map(FlooredFloat, iterable))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With