Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any Python implementation of set() with key argument?

Tags:

python

set

Question

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.

Desired effect

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'}

Which to choose

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'.

Answer

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())
like image 880
Thijs van Ede Avatar asked Feb 04 '23 22:02

Thijs van Ede


2 Answers

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}
like image 142
Daniel Roseman Avatar answered Feb 06 '23 14:02

Daniel Roseman


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))
like image 22
deceze Avatar answered Feb 06 '23 14:02

deceze