import random try: set except: from sets import Set as set def _get_value(obj, attr): if not attr: return obj elif isinstance(obj, dict): return obj[attr] else: return getattr(obj, attr) def all_are_duplicates(items, attr=None): """Returns True if all given items has the same value for a given attribute""" return len(set([_get_value(item, attr) for item in items])) == 1 def real_shuffle(l, attr=None, remove_duplicates=False): """This function make a 'real' shuffle of a list, without only depend on a randomized shuffling but looping along the list to make sure they aren't repeating a given attribute.""" # Make a copy of the list ret = list(l) # Just returns it if has 1 or less items if len(ret) <= 1: return ret # Randomic shuffling random.shuffle(ret) # Loop along the list to make 'real' shuffle new_list = [] while not all_are_duplicates(ret, attr): for cur_index in range(len(ret)): if not new_list or _get_value(ret[cur_index], attr) != _get_value(new_list[-1], attr): new_list.append(ret.pop(cur_index)) break new_list += ret # Remove the duplicates if remove_duplicates: while len(new_list) > 1 and _get_value(new_list[-1], attr) == _get_value(new_list[-2], attr): new_list.pop(-1) return new_list if __name__ == '__main__': class Animal(object): name = str() kind = str() def __init__(self, name, kind): self.name, self.kind = name, kind def __str__(self): return '%s/%s'%(self.name, self.kind) animals = [ Animal('a1', 'lion'), Animal('b1', 'tiger'), Animal('a2', 'lion'), Animal('a3', 'lion'), Animal('a5', 'lion'), Animal('c1', 'lion'), Animal('a4', 'lion'), Animal('b2', 'tiger'), Animal('b3', 'tiger'), Animal('a6', 'lion'), Animal('c2', 'cat'), Animal('b4', 'tiger'), ] print all_are_duplicates(animals, 'kind'), all_are_duplicates(animals[2:5], 'kind') print '\n\nOriginal:' print ' ', ', '.join(map(str, animals)) print '\n\nShuffled by Python' animals2 = list(animals) random.shuffle(animals2) print ' ', ', '.join(map(str, animals2)) print '\n\nShuffled by me' animals3 = real_shuffle(animals, 'kind') print ' ', ', '.join(map(str, animals3)) print '\n\nShuffled by me - removing duplicates' animals3 = real_shuffle(animals, 'kind', True) print ' ', ', '.join(map(str, animals3)) print '\n\n'