0

I have a set (any collection type will do for all I care) like this.

myset = {{a},{b},{c},{d,e}, {d,f}}

I am now trying to check whether two elements {a} and {d} exist in myset and if so merge {a} with {d,e}. If on the other hand I am checking {d} and {f}, then I will merge {d,e} and {d,f} to get {d,e,f}.

I will be grateful if any one shows me the direction towards the solution.

5
  • 5
    Will you please explain your logic in more detail? What is the logic by selection {a} to add in set if {a} and {d} exits? Commented Nov 25, 2014 at 7:33
  • your question is unclear. Commented Nov 25, 2014 at 8:26
  • what would happen in this case: {{a,b},{a,c},{b,d},{b,e}} and you are checking for {a} and {b} Commented Nov 25, 2014 at 8:28
  • I will never have such a set as {{a,b},{a,c},{b,d},{b,e}}. I am building my cluster from a set having {{a},{b},{c},{d}} at the beginning. In the first iteration I may merge {a} and {b} with the resulting output {{ab},{c},{d}}. In the second, I may search for {a} and {c} resulting with {{abc},{d}} Commented Nov 25, 2014 at 8:35
  • The problem I have basically is, given a set (myset) and two search elements i and j, newmyset = myset - i - j U (i,j) Commented Nov 25, 2014 at 8:40

4 Answers 4

2

This might not be the most pythonic approach but it should work,let me know if it doesn't and I have done it for lists,you could do it for sets using a similar approach

def get_member(a,the_list):
    if a in the_list:
        return a
    else:
        for elem in the_list:
            if isinstance(elem,list):
                if a in elem:
                    return elem
    return None

def merge_member(a,b,the_list):
    get_member_a = get_member(a,the_list)
    get_member_b = get_member(b,the_list)
    if get_member_a and get_member_b:
        the_list.remove(get_member_a)
        the_list.remove(get_member_b)
        if isinstance(get_member_b,list):
            get_member_b.extend(get_member_a)
            the_list.append(get_member_b)
        elif isinstance(get_member_a,list):
            get_member_a.extend(get_member_b)
            the_list.append(get_member_a)
        else:
            the_list.append([get_member_b,get_member_a])
    return the_list
Sign up to request clarification or add additional context in comments.

2 Comments

This worked fine for me. Changing it to a set is a problem however as python sets do not accept [unhashable] sets or lists as elements. Anyways, I have at least a solution for the problemat hand.
Yep,you'll have to use frozensets,though I think you already knew that.
2

First of all: you cannot build a set of sets in python, as a set needs to contain hashable values while a set itself is not hashable.

But of course you could do the same with a list of of sets. The probably fastest and most pythonic solution should be like:

myset = [{1}, {2}, {3}, {4, 5}, {5, 6}]
merged_set = set().union(*myset)

(set.union cannot only be used with one parameter, but with any number of parameters)

Comments

0

I appears that we need to improve the merge_member block to handle such cases where we have [['a'],['b'],['c'],['d'],['e','f','g']], as the_list and we are looking for 'e' and 'f'.

def merge_member(a,b,the_list):
    get_member_a = get_member(a, the_list)
    get_member_b = get_member(b, the_list)
    if get_member_a and get_member_b:
        if get_member_a.__eq__(get_member_b):
           the_list.remove(get_member_a)
           if isinstance(get_member_b, list):
              the_list.append(get_member_b)
        else:
           the_list.remove(get_member_a)
           the_list.remove(get_member_b)
           if isinstance(get_member_b, list):
              get_member_b.extend(get_member_a)
              the_list.append(get_member_b)
           elif isinstance(get_member_a, list):
              get_member_a.extend(get_member_b)
              the_list.append(get_member_a)
           else:
              the_list.append([get_member_b,get_member_a])
    return the_list

Comments

0

You can use this method to merge a set list:

from functools import reduce # for python3
myset = [{'a'}, {'b'}, {'c'}, {'d','e'}, {'d','f'}] 
reduce(lambda x, y: {*x, *y}, myset)

output:

{'a', 'b', 'c', 'd', 'e', 'f'}

Solution for the question:

from functools import reduce # for python3
myset = [{'a'}, {'b'}, {'c'}, {'d','e'}, {'d','f'}]  # define your set list

def get_element_set(elem, myset):
    try:
        z = [x for x in myset if elem in x] 
        result = reduce(lambda x, y: {*x, *y}, z)
        return result
    except TypeError as e:
        print('Element "%s" is not exist in myset!' % elem)
        return {}

def merge_member(elem_list, myset):
    z = map(lambda elem: get_element_set(elem, myset), elem_list)
    result = reduce(lambda x, y: {*x, *y}, z)
    return result

Example:

get_element_set('d', myset) # {'d', 'e', 'f'}
get_element_set('g', myset) # Element "g" is not exist in myset! {}
merge_member(['f', 'd'], myset) # {'d', 'e', 'f'}
merge_member(['a', 'd'], myset) # {'a', 'd', 'e', 'f'}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.