Python matching elements in lists of lists and combining into a single set

I have data where I've stored a set of values in lists in a list. These lists will contain mostly unique data, however one element is guaranteed to be the same as one element in another of the lists. What I'm looking to do is iterate over those lists (no set total number of lists), match two nested lists using the shared element and then combine these two lists. This would need to be done for every list in the list.

Example:

my_list = [[1, 2, 3, 4, Hello], [5, 6, 7, 8, Hello], 
          [9, 10, 11, 12, Bye], [13, 14, 15, 16, Bye], 
          [17, 18, 19, 20, Python], [21, 22, 23, 24, Python]]

Desired result:

my_list1 = [1, 2, 3, 4, Hello, 5, 6, 7, 8, Hello]
my_list2 = [9, 10, 11, 12, Bye, 13, 14, 15, 16, Bye]
my_list3 = [17, 18, 19, 20, Python, 21, 22, 23, 24, Python]
....

In this case they will have matched on Hello, Bye and Python. The matching lists don't necessarily immediatelly follow each other.

I've found some ways to search within list of lists for matching elements but they seem to be looking and pulling the shared element and I can't find a way to merge two sets once found.

I'm fairly new to Python so although I know what I would like it to do I don't know if I'm going down the right path and if Python has the functionality to do this so any help would be greatly appreciated.

Thanks,

Edit: It will always be the last element in each list that is the matching value, the lists will always be structured in this format and not random

1 answer

  • answered 2018-01-04 20:12 Patrick Artner

    my_list = [[1, 2, 3, 4, "Hello"], [5, 6, 7, 8, "Hello"], 
              [9, 10, 11, 12, "Bye"], [13, 14, 15, 16, "Bye"], 
              [17, 18, 19, 20, "Python"], [21, 22, 23, 24, "Python"]]
    

    Faster way by @JonClements:

    d = {} 
    for lst in my_list: 
        d.setdefault(lst[-1], []).extend(lst)    
    
    print(d.values)
    

    https://docs.python.org/3/library/stdtypes.html#dict

    • dictionary.setDefault(key,defaultValueIfKeyNotPresent) returns the keys value if already present in the dictionary, else creates the key with the given
    • defaultValueIfKeyNotPresent (or None if not explicitly given). .extend(lst) is a conveniencemethod on lists that extends the list by some other iterable.

    He also proposes another way with itertools and lambda - see comments.


    My step by step way:

    results = []
    for n in set(x[-1] for x in my_list): # just get all last elements as set
        sameLastElement = [x for x in my_list if x[-1] == n] # get all sublists that match
        same = [] # accumulate sub lists into one list
        for a in sameLastElement:
            same +=  a
        results.append(same) # put into result array
    
    print (results) # done
    

    Output - had to change the last element to string:

    [[1, 2, 3, 4, 'Hello', 5, 6, 7, 8, 'Hello'], 
     [9, 10, 11, 12, 'Bye', 13, 14, 15, 16, 'Bye'], 
     [17, 18, 19, 20, 'Python', 21, 22, 23, 24, 'Python']]
    

    You can deconstruct thisresult if you know how many will be in there, or simply iterate over all merged sublists.

    list_a, list_b, list_c = results
    

    or

    for n in results:
        # do smth with each single merged list