Merge tuples with the same key

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
8
down vote

favorite












How to merge a tuple with the same key



list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]


and turn them into



list_2 = [("AAA", [123, 456]), ("AAW", [147, 124])]









share|improve this question









New contributor




Theprofessor14 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.















  • 1




    Related: Python: merge lists of tuples based on its values
    – Aran-Fey
    8 hours ago






  • 2




    all those years and not a single exact dupe... I had a good look. Maybe it's somewhere, well...
    – Jean-François Fabre
    7 hours ago














up vote
8
down vote

favorite












How to merge a tuple with the same key



list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]


and turn them into



list_2 = [("AAA", [123, 456]), ("AAW", [147, 124])]









share|improve this question









New contributor




Theprofessor14 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.















  • 1




    Related: Python: merge lists of tuples based on its values
    – Aran-Fey
    8 hours ago






  • 2




    all those years and not a single exact dupe... I had a good look. Maybe it's somewhere, well...
    – Jean-François Fabre
    7 hours ago












up vote
8
down vote

favorite









up vote
8
down vote

favorite











How to merge a tuple with the same key



list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]


and turn them into



list_2 = [("AAA", [123, 456]), ("AAW", [147, 124])]









share|improve this question









New contributor




Theprofessor14 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











How to merge a tuple with the same key



list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]


and turn them into



list_2 = [("AAA", [123, 456]), ("AAW", [147, 124])]






python tuples






share|improve this question









New contributor




Theprofessor14 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




Theprofessor14 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 16 mins ago









codeforester

15.9k73555




15.9k73555






New contributor




Theprofessor14 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 8 hours ago









Theprofessor14

442




442




New contributor




Theprofessor14 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Theprofessor14 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Theprofessor14 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







  • 1




    Related: Python: merge lists of tuples based on its values
    – Aran-Fey
    8 hours ago






  • 2




    all those years and not a single exact dupe... I had a good look. Maybe it's somewhere, well...
    – Jean-François Fabre
    7 hours ago












  • 1




    Related: Python: merge lists of tuples based on its values
    – Aran-Fey
    8 hours ago






  • 2




    all those years and not a single exact dupe... I had a good look. Maybe it's somewhere, well...
    – Jean-François Fabre
    7 hours ago







1




1




Related: Python: merge lists of tuples based on its values
– Aran-Fey
8 hours ago




Related: Python: merge lists of tuples based on its values
– Aran-Fey
8 hours ago




2




2




all those years and not a single exact dupe... I had a good look. Maybe it's somewhere, well...
– Jean-François Fabre
7 hours ago




all those years and not a single exact dupe... I had a good look. Maybe it's somewhere, well...
– Jean-François Fabre
7 hours ago












4 Answers
4






active

oldest

votes

















up vote
8
down vote













The most performant approach is to use a collections.defaultdict dictionary to store data as an expanding list, then convert back to tuple/list if needed:



import collections

list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]

c = collections.defaultdict(list)
for a,b in list_1:
c[a].extend(b) # add to existing list or create a new one

list_2 = list(c.items())


result:



[('AAW', [147, 124]), ('AAA', [123, 456])]


note that the converted data is probably better left as dictionary. Converting to list again loses the "key" feature of the dictionary.



On the other hand, if you want to retain the order of the "keys" of the original list of tuples, unless you're using python 3.6/3.7, you'd have to create a list with the original "keys" (ordered, unique), then rebuild the list from the dictionary. Or use an OrderedDict but then you cannot use defaultdict (or use a recipe)






share|improve this answer


















  • 1




    Note that this answer would not necessarily retain the order of the original list, if that is a consideration.
    – blhsing
    7 hours ago










  • true, unless you're using python 3.7. To retain the original order you'd have to create a list with the original "keys" (ordered, unique), then rebuild the list from the dictionary.
    – Jean-François Fabre
    7 hours ago


















up vote
4
down vote













You can use a dict to keep track of the indices of each key to keep the time complexity O(n):



list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]
list_2 =
i =
for k, s in list_1:
if k not in i:
list_2.append((k, s))
i[k] = len(i)
else:
list_2[i[k]][1].extend(s)


list_2 would become:



[('AAA', [123, 456]), ('AAW', [147, 124])]





share|improve this answer





























    up vote
    1
    down vote













    Similarly to other answers, you can use a dictionary to associate each key with a list of values. This is implemented in the function merge_by_keys in the code snippet below.



    import pprint

    list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]
    list_2 = [("AAA", [123, 456]), ("AAW", [147, 124])]

    def merge_by_key(ts):

    d =
    for t in ts:
    key = t[0]
    values = t[1]
    if key not in d:
    d[key] = values[:]
    else:
    d[key].extend(values)

    return d.items()



    result = merge_by_key(list_1)

    pprint.pprint(result)





    share|improve this answer




















    • Why are you manually creating list_2?
      – codeforester
      20 mins ago

















    up vote
    1
    down vote













    You can create a dictionary and loop through the list. If the item present in dictionary append the value to already existing list else assign the value to key.



    dict_1 = 
    for item in list_1:
    if item[0] in dict_1:
    dict_1[item[0]].append(item[1][0])
    else:
    dict_1[item[0]] = item[1]
    list_2 = list(dict_1.items())





    share|improve this answer










    New contributor




    S.Harish is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.

















    • It does the merge but doesn't retain the original order in the list. The result I got is: [('AAW', [147, 124]), ('AAA', [123, 456])] - AAA should have been the first element as in the original list.
      – codeforester
      22 mins ago











    Your Answer





    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );






    Theprofessor14 is a new contributor. Be nice, and check out our Code of Conduct.









     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52454582%2fmerge-tuples-with-the-same-key%23new-answer', 'question_page');

    );

    Post as a guest






























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    8
    down vote













    The most performant approach is to use a collections.defaultdict dictionary to store data as an expanding list, then convert back to tuple/list if needed:



    import collections

    list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]

    c = collections.defaultdict(list)
    for a,b in list_1:
    c[a].extend(b) # add to existing list or create a new one

    list_2 = list(c.items())


    result:



    [('AAW', [147, 124]), ('AAA', [123, 456])]


    note that the converted data is probably better left as dictionary. Converting to list again loses the "key" feature of the dictionary.



    On the other hand, if you want to retain the order of the "keys" of the original list of tuples, unless you're using python 3.6/3.7, you'd have to create a list with the original "keys" (ordered, unique), then rebuild the list from the dictionary. Or use an OrderedDict but then you cannot use defaultdict (or use a recipe)






    share|improve this answer


















    • 1




      Note that this answer would not necessarily retain the order of the original list, if that is a consideration.
      – blhsing
      7 hours ago










    • true, unless you're using python 3.7. To retain the original order you'd have to create a list with the original "keys" (ordered, unique), then rebuild the list from the dictionary.
      – Jean-François Fabre
      7 hours ago















    up vote
    8
    down vote













    The most performant approach is to use a collections.defaultdict dictionary to store data as an expanding list, then convert back to tuple/list if needed:



    import collections

    list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]

    c = collections.defaultdict(list)
    for a,b in list_1:
    c[a].extend(b) # add to existing list or create a new one

    list_2 = list(c.items())


    result:



    [('AAW', [147, 124]), ('AAA', [123, 456])]


    note that the converted data is probably better left as dictionary. Converting to list again loses the "key" feature of the dictionary.



    On the other hand, if you want to retain the order of the "keys" of the original list of tuples, unless you're using python 3.6/3.7, you'd have to create a list with the original "keys" (ordered, unique), then rebuild the list from the dictionary. Or use an OrderedDict but then you cannot use defaultdict (or use a recipe)






    share|improve this answer


















    • 1




      Note that this answer would not necessarily retain the order of the original list, if that is a consideration.
      – blhsing
      7 hours ago










    • true, unless you're using python 3.7. To retain the original order you'd have to create a list with the original "keys" (ordered, unique), then rebuild the list from the dictionary.
      – Jean-François Fabre
      7 hours ago













    up vote
    8
    down vote










    up vote
    8
    down vote









    The most performant approach is to use a collections.defaultdict dictionary to store data as an expanding list, then convert back to tuple/list if needed:



    import collections

    list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]

    c = collections.defaultdict(list)
    for a,b in list_1:
    c[a].extend(b) # add to existing list or create a new one

    list_2 = list(c.items())


    result:



    [('AAW', [147, 124]), ('AAA', [123, 456])]


    note that the converted data is probably better left as dictionary. Converting to list again loses the "key" feature of the dictionary.



    On the other hand, if you want to retain the order of the "keys" of the original list of tuples, unless you're using python 3.6/3.7, you'd have to create a list with the original "keys" (ordered, unique), then rebuild the list from the dictionary. Or use an OrderedDict but then you cannot use defaultdict (or use a recipe)






    share|improve this answer














    The most performant approach is to use a collections.defaultdict dictionary to store data as an expanding list, then convert back to tuple/list if needed:



    import collections

    list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]

    c = collections.defaultdict(list)
    for a,b in list_1:
    c[a].extend(b) # add to existing list or create a new one

    list_2 = list(c.items())


    result:



    [('AAW', [147, 124]), ('AAA', [123, 456])]


    note that the converted data is probably better left as dictionary. Converting to list again loses the "key" feature of the dictionary.



    On the other hand, if you want to retain the order of the "keys" of the original list of tuples, unless you're using python 3.6/3.7, you'd have to create a list with the original "keys" (ordered, unique), then rebuild the list from the dictionary. Or use an OrderedDict but then you cannot use defaultdict (or use a recipe)







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 7 hours ago

























    answered 8 hours ago









    Jean-François Fabre

    92.1k847102




    92.1k847102







    • 1




      Note that this answer would not necessarily retain the order of the original list, if that is a consideration.
      – blhsing
      7 hours ago










    • true, unless you're using python 3.7. To retain the original order you'd have to create a list with the original "keys" (ordered, unique), then rebuild the list from the dictionary.
      – Jean-François Fabre
      7 hours ago













    • 1




      Note that this answer would not necessarily retain the order of the original list, if that is a consideration.
      – blhsing
      7 hours ago










    • true, unless you're using python 3.7. To retain the original order you'd have to create a list with the original "keys" (ordered, unique), then rebuild the list from the dictionary.
      – Jean-François Fabre
      7 hours ago








    1




    1




    Note that this answer would not necessarily retain the order of the original list, if that is a consideration.
    – blhsing
    7 hours ago




    Note that this answer would not necessarily retain the order of the original list, if that is a consideration.
    – blhsing
    7 hours ago












    true, unless you're using python 3.7. To retain the original order you'd have to create a list with the original "keys" (ordered, unique), then rebuild the list from the dictionary.
    – Jean-François Fabre
    7 hours ago





    true, unless you're using python 3.7. To retain the original order you'd have to create a list with the original "keys" (ordered, unique), then rebuild the list from the dictionary.
    – Jean-François Fabre
    7 hours ago













    up vote
    4
    down vote













    You can use a dict to keep track of the indices of each key to keep the time complexity O(n):



    list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]
    list_2 =
    i =
    for k, s in list_1:
    if k not in i:
    list_2.append((k, s))
    i[k] = len(i)
    else:
    list_2[i[k]][1].extend(s)


    list_2 would become:



    [('AAA', [123, 456]), ('AAW', [147, 124])]





    share|improve this answer


























      up vote
      4
      down vote













      You can use a dict to keep track of the indices of each key to keep the time complexity O(n):



      list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]
      list_2 =
      i =
      for k, s in list_1:
      if k not in i:
      list_2.append((k, s))
      i[k] = len(i)
      else:
      list_2[i[k]][1].extend(s)


      list_2 would become:



      [('AAA', [123, 456]), ('AAW', [147, 124])]





      share|improve this answer
























        up vote
        4
        down vote










        up vote
        4
        down vote









        You can use a dict to keep track of the indices of each key to keep the time complexity O(n):



        list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]
        list_2 =
        i =
        for k, s in list_1:
        if k not in i:
        list_2.append((k, s))
        i[k] = len(i)
        else:
        list_2[i[k]][1].extend(s)


        list_2 would become:



        [('AAA', [123, 456]), ('AAW', [147, 124])]





        share|improve this answer














        You can use a dict to keep track of the indices of each key to keep the time complexity O(n):



        list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]
        list_2 =
        i =
        for k, s in list_1:
        if k not in i:
        list_2.append((k, s))
        i[k] = len(i)
        else:
        list_2[i[k]][1].extend(s)


        list_2 would become:



        [('AAA', [123, 456]), ('AAW', [147, 124])]






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 31 mins ago









        codeforester

        15.9k73555




        15.9k73555










        answered 8 hours ago









        blhsing

        16.5k2631




        16.5k2631




















            up vote
            1
            down vote













            Similarly to other answers, you can use a dictionary to associate each key with a list of values. This is implemented in the function merge_by_keys in the code snippet below.



            import pprint

            list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]
            list_2 = [("AAA", [123, 456]), ("AAW", [147, 124])]

            def merge_by_key(ts):

            d =
            for t in ts:
            key = t[0]
            values = t[1]
            if key not in d:
            d[key] = values[:]
            else:
            d[key].extend(values)

            return d.items()



            result = merge_by_key(list_1)

            pprint.pprint(result)





            share|improve this answer




















            • Why are you manually creating list_2?
              – codeforester
              20 mins ago














            up vote
            1
            down vote













            Similarly to other answers, you can use a dictionary to associate each key with a list of values. This is implemented in the function merge_by_keys in the code snippet below.



            import pprint

            list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]
            list_2 = [("AAA", [123, 456]), ("AAW", [147, 124])]

            def merge_by_key(ts):

            d =
            for t in ts:
            key = t[0]
            values = t[1]
            if key not in d:
            d[key] = values[:]
            else:
            d[key].extend(values)

            return d.items()



            result = merge_by_key(list_1)

            pprint.pprint(result)





            share|improve this answer




















            • Why are you manually creating list_2?
              – codeforester
              20 mins ago












            up vote
            1
            down vote










            up vote
            1
            down vote









            Similarly to other answers, you can use a dictionary to associate each key with a list of values. This is implemented in the function merge_by_keys in the code snippet below.



            import pprint

            list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]
            list_2 = [("AAA", [123, 456]), ("AAW", [147, 124])]

            def merge_by_key(ts):

            d =
            for t in ts:
            key = t[0]
            values = t[1]
            if key not in d:
            d[key] = values[:]
            else:
            d[key].extend(values)

            return d.items()



            result = merge_by_key(list_1)

            pprint.pprint(result)





            share|improve this answer












            Similarly to other answers, you can use a dictionary to associate each key with a list of values. This is implemented in the function merge_by_keys in the code snippet below.



            import pprint

            list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]
            list_2 = [("AAA", [123, 456]), ("AAW", [147, 124])]

            def merge_by_key(ts):

            d =
            for t in ts:
            key = t[0]
            values = t[1]
            if key not in d:
            d[key] = values[:]
            else:
            d[key].extend(values)

            return d.items()



            result = merge_by_key(list_1)

            pprint.pprint(result)






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered 7 hours ago









            Odysseas

            445210




            445210











            • Why are you manually creating list_2?
              – codeforester
              20 mins ago
















            • Why are you manually creating list_2?
              – codeforester
              20 mins ago















            Why are you manually creating list_2?
            – codeforester
            20 mins ago




            Why are you manually creating list_2?
            – codeforester
            20 mins ago










            up vote
            1
            down vote













            You can create a dictionary and loop through the list. If the item present in dictionary append the value to already existing list else assign the value to key.



            dict_1 = 
            for item in list_1:
            if item[0] in dict_1:
            dict_1[item[0]].append(item[1][0])
            else:
            dict_1[item[0]] = item[1]
            list_2 = list(dict_1.items())





            share|improve this answer










            New contributor




            S.Harish is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.

















            • It does the merge but doesn't retain the original order in the list. The result I got is: [('AAW', [147, 124]), ('AAA', [123, 456])] - AAA should have been the first element as in the original list.
              – codeforester
              22 mins ago















            up vote
            1
            down vote













            You can create a dictionary and loop through the list. If the item present in dictionary append the value to already existing list else assign the value to key.



            dict_1 = 
            for item in list_1:
            if item[0] in dict_1:
            dict_1[item[0]].append(item[1][0])
            else:
            dict_1[item[0]] = item[1]
            list_2 = list(dict_1.items())





            share|improve this answer










            New contributor




            S.Harish is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.

















            • It does the merge but doesn't retain the original order in the list. The result I got is: [('AAW', [147, 124]), ('AAA', [123, 456])] - AAA should have been the first element as in the original list.
              – codeforester
              22 mins ago













            up vote
            1
            down vote










            up vote
            1
            down vote









            You can create a dictionary and loop through the list. If the item present in dictionary append the value to already existing list else assign the value to key.



            dict_1 = 
            for item in list_1:
            if item[0] in dict_1:
            dict_1[item[0]].append(item[1][0])
            else:
            dict_1[item[0]] = item[1]
            list_2 = list(dict_1.items())





            share|improve this answer










            New contributor




            S.Harish is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.









            You can create a dictionary and loop through the list. If the item present in dictionary append the value to already existing list else assign the value to key.



            dict_1 = 
            for item in list_1:
            if item[0] in dict_1:
            dict_1[item[0]].append(item[1][0])
            else:
            dict_1[item[0]] = item[1]
            list_2 = list(dict_1.items())






            share|improve this answer










            New contributor




            S.Harish is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.









            share|improve this answer



            share|improve this answer








            edited 23 mins ago









            codeforester

            15.9k73555




            15.9k73555






            New contributor




            S.Harish is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.









            answered 8 hours ago









            S.Harish

            644




            644




            New contributor




            S.Harish is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.





            New contributor





            S.Harish is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.






            S.Harish is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.











            • It does the merge but doesn't retain the original order in the list. The result I got is: [('AAW', [147, 124]), ('AAA', [123, 456])] - AAA should have been the first element as in the original list.
              – codeforester
              22 mins ago

















            • It does the merge but doesn't retain the original order in the list. The result I got is: [('AAW', [147, 124]), ('AAA', [123, 456])] - AAA should have been the first element as in the original list.
              – codeforester
              22 mins ago
















            It does the merge but doesn't retain the original order in the list. The result I got is: [('AAW', [147, 124]), ('AAA', [123, 456])] - AAA should have been the first element as in the original list.
            – codeforester
            22 mins ago





            It does the merge but doesn't retain the original order in the list. The result I got is: [('AAW', [147, 124]), ('AAA', [123, 456])] - AAA should have been the first element as in the original list.
            – codeforester
            22 mins ago











            Theprofessor14 is a new contributor. Be nice, and check out our Code of Conduct.









             

            draft saved


            draft discarded


















            Theprofessor14 is a new contributor. Be nice, and check out our Code of Conduct.












            Theprofessor14 is a new contributor. Be nice, and check out our Code of Conduct.











            Theprofessor14 is a new contributor. Be nice, and check out our Code of Conduct.













             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52454582%2fmerge-tuples-with-the-same-key%23new-answer', 'question_page');

            );

            Post as a guest













































































            Comments

            Popular posts from this blog

            Long meetings (6-7 hours a day): Being “babysat” by supervisor

            Is the Concept of Multiple Fantasy Races Scientifically Flawed? [closed]

            Confectionery