Assign a unique number to duplicate items in a list
As you've already implemented Curtain.__eq__, if you also implement Curtain.__hash__ you can use it as a dictionary (or collections.Counter...) key, or a set member:

def __hash__(self):
    return hash(self.type) ^ hash(self.fabric)


Now make_unique is trivial:

def make_unique(self, original_list):
    return set(original_list)


(Note: if you require order to be retained, this will need additional work.)

This also allows you to easily determine how many of each distinct Curtain you have:

&gt;&gt;&gt; from collections import Counter
&gt;&gt;&gt; Counter(curtains)
Counter({&lt;__main__.Curtain object at 0x02A15190&gt;: 3, 
         &lt;__main__.Curtain object at 0x031A0CF0&gt;: 2, 
         &lt;__main__.Curtain object at 0x031A0ED0&gt;: 2, 
         &lt;__main__.Curtain object at 0x0329EA30&gt;: 1})


(Note: implementing Curtain.__repr__ would make this more readable!)



As pointed out in the comments, the __hash__ implementation I suggest has an issue - if either attribute type or fabric is changed, the hash will be different. You could protect these attributes by making them "read-only" using properties:

class Curtain(object):

    def __init__(self, type, ...):
        self._type = type # note leading underscore on attribute

    @property # defining setter but no getter
    def type(self):
        return self._type




Alternatively, you can implement Curtain.__lt__ etc., then sort the list and use itertools.groupby to get your groups of "equal" Curtains.



Either way, I would not implement CreatSet as a class, there's no need (as should be clear from the fact that there is no __init__ and no class or instance attributes). Just have one class, and two functions:

class Curtain(object):
    ...

def create_set(curtains):
    ...

def make_unique(curtains):
    ...


Your code is generally compliant with the style guide (well done!) but you could do with some explanatory docstrings.