Merge a dict element in a list of dicts using Python












9















I have a list that includes dictionaries (List[Dict, Dict, ...]) , I would like to uniqify the list based on two keys, but I want to retain the value of another key in the dictionary to make sure I do not lose it by making a list in the key I want to retain. I am using Python for the code. If it is of any significance Python 3.x to be exact.



Let's assume I have the following list of dictionaries with three keys: number, favorite, and color. I want to uniqify the list elements using the keys number and favorite. However for the dictionaries that have the same values number and favorite, I'd like to add a list under the key color to make sure I have all the colors for the same combination of number and favorite. This list should also be unique since it shouldn't need the repeated colors for the same combination. However, if there is only one element for the key color in the final result, it should be a string and not a list.



lst = [
{'number': 1, 'favorite': False, 'color': 'red'},
{'number': 1, 'favorite': False, 'color': 'green'},
{'number': 1, 'favorite': False, 'color': 'red'},
{'number': 1, 'favorite': True, 'color': 'red'},
{'number': 2, 'favorite': False, 'color': 'red'}]


Using the aforementioned uniqify, I would get the following result:



lst = [
{'number': 1, 'favorite': False, 'color': ['red', 'green']},
{'number': 1, 'favorite': True, 'color': 'red'},
{'number': 2, 'favorite': False, 'color': 'red'},
]


Note that there is only one instance of red where the number is 1 and favorite is False even though it appeared twice in the list before it was uniqified. Also note that when there is only one element for the key color in the second dict, it is a string and not a list.










share|improve this question

























  • Are you interested in using pandas for this?

    – coldspeed
    2 hours ago











  • {'red', 'green'} This still doesn't make any sense.

    – Praind
    2 hours ago











  • it basically is a list that serves as a value to the key color @Praind

    – KaanTheGuru
    2 hours ago











  • Is it necessary to have a string instead of a list if there's only one element?

    – Praind
    1 hour ago











  • yes it is necessary, will edit question to include that detail. Thank you @Praind

    – KaanTheGuru
    1 hour ago
















9















I have a list that includes dictionaries (List[Dict, Dict, ...]) , I would like to uniqify the list based on two keys, but I want to retain the value of another key in the dictionary to make sure I do not lose it by making a list in the key I want to retain. I am using Python for the code. If it is of any significance Python 3.x to be exact.



Let's assume I have the following list of dictionaries with three keys: number, favorite, and color. I want to uniqify the list elements using the keys number and favorite. However for the dictionaries that have the same values number and favorite, I'd like to add a list under the key color to make sure I have all the colors for the same combination of number and favorite. This list should also be unique since it shouldn't need the repeated colors for the same combination. However, if there is only one element for the key color in the final result, it should be a string and not a list.



lst = [
{'number': 1, 'favorite': False, 'color': 'red'},
{'number': 1, 'favorite': False, 'color': 'green'},
{'number': 1, 'favorite': False, 'color': 'red'},
{'number': 1, 'favorite': True, 'color': 'red'},
{'number': 2, 'favorite': False, 'color': 'red'}]


Using the aforementioned uniqify, I would get the following result:



lst = [
{'number': 1, 'favorite': False, 'color': ['red', 'green']},
{'number': 1, 'favorite': True, 'color': 'red'},
{'number': 2, 'favorite': False, 'color': 'red'},
]


Note that there is only one instance of red where the number is 1 and favorite is False even though it appeared twice in the list before it was uniqified. Also note that when there is only one element for the key color in the second dict, it is a string and not a list.










share|improve this question

























  • Are you interested in using pandas for this?

    – coldspeed
    2 hours ago











  • {'red', 'green'} This still doesn't make any sense.

    – Praind
    2 hours ago











  • it basically is a list that serves as a value to the key color @Praind

    – KaanTheGuru
    2 hours ago











  • Is it necessary to have a string instead of a list if there's only one element?

    – Praind
    1 hour ago











  • yes it is necessary, will edit question to include that detail. Thank you @Praind

    – KaanTheGuru
    1 hour ago














9












9








9








I have a list that includes dictionaries (List[Dict, Dict, ...]) , I would like to uniqify the list based on two keys, but I want to retain the value of another key in the dictionary to make sure I do not lose it by making a list in the key I want to retain. I am using Python for the code. If it is of any significance Python 3.x to be exact.



Let's assume I have the following list of dictionaries with three keys: number, favorite, and color. I want to uniqify the list elements using the keys number and favorite. However for the dictionaries that have the same values number and favorite, I'd like to add a list under the key color to make sure I have all the colors for the same combination of number and favorite. This list should also be unique since it shouldn't need the repeated colors for the same combination. However, if there is only one element for the key color in the final result, it should be a string and not a list.



lst = [
{'number': 1, 'favorite': False, 'color': 'red'},
{'number': 1, 'favorite': False, 'color': 'green'},
{'number': 1, 'favorite': False, 'color': 'red'},
{'number': 1, 'favorite': True, 'color': 'red'},
{'number': 2, 'favorite': False, 'color': 'red'}]


Using the aforementioned uniqify, I would get the following result:



lst = [
{'number': 1, 'favorite': False, 'color': ['red', 'green']},
{'number': 1, 'favorite': True, 'color': 'red'},
{'number': 2, 'favorite': False, 'color': 'red'},
]


Note that there is only one instance of red where the number is 1 and favorite is False even though it appeared twice in the list before it was uniqified. Also note that when there is only one element for the key color in the second dict, it is a string and not a list.










share|improve this question
















I have a list that includes dictionaries (List[Dict, Dict, ...]) , I would like to uniqify the list based on two keys, but I want to retain the value of another key in the dictionary to make sure I do not lose it by making a list in the key I want to retain. I am using Python for the code. If it is of any significance Python 3.x to be exact.



Let's assume I have the following list of dictionaries with three keys: number, favorite, and color. I want to uniqify the list elements using the keys number and favorite. However for the dictionaries that have the same values number and favorite, I'd like to add a list under the key color to make sure I have all the colors for the same combination of number and favorite. This list should also be unique since it shouldn't need the repeated colors for the same combination. However, if there is only one element for the key color in the final result, it should be a string and not a list.



lst = [
{'number': 1, 'favorite': False, 'color': 'red'},
{'number': 1, 'favorite': False, 'color': 'green'},
{'number': 1, 'favorite': False, 'color': 'red'},
{'number': 1, 'favorite': True, 'color': 'red'},
{'number': 2, 'favorite': False, 'color': 'red'}]


Using the aforementioned uniqify, I would get the following result:



lst = [
{'number': 1, 'favorite': False, 'color': ['red', 'green']},
{'number': 1, 'favorite': True, 'color': 'red'},
{'number': 2, 'favorite': False, 'color': 'red'},
]


Note that there is only one instance of red where the number is 1 and favorite is False even though it appeared twice in the list before it was uniqified. Also note that when there is only one element for the key color in the second dict, it is a string and not a list.







python python-3.x list dictionary unique






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 1 hour ago







KaanTheGuru

















asked 2 hours ago









KaanTheGuruKaanTheGuru

607




607













  • Are you interested in using pandas for this?

    – coldspeed
    2 hours ago











  • {'red', 'green'} This still doesn't make any sense.

    – Praind
    2 hours ago











  • it basically is a list that serves as a value to the key color @Praind

    – KaanTheGuru
    2 hours ago











  • Is it necessary to have a string instead of a list if there's only one element?

    – Praind
    1 hour ago











  • yes it is necessary, will edit question to include that detail. Thank you @Praind

    – KaanTheGuru
    1 hour ago



















  • Are you interested in using pandas for this?

    – coldspeed
    2 hours ago











  • {'red', 'green'} This still doesn't make any sense.

    – Praind
    2 hours ago











  • it basically is a list that serves as a value to the key color @Praind

    – KaanTheGuru
    2 hours ago











  • Is it necessary to have a string instead of a list if there's only one element?

    – Praind
    1 hour ago











  • yes it is necessary, will edit question to include that detail. Thank you @Praind

    – KaanTheGuru
    1 hour ago

















Are you interested in using pandas for this?

– coldspeed
2 hours ago





Are you interested in using pandas for this?

– coldspeed
2 hours ago













{'red', 'green'} This still doesn't make any sense.

– Praind
2 hours ago





{'red', 'green'} This still doesn't make any sense.

– Praind
2 hours ago













it basically is a list that serves as a value to the key color @Praind

– KaanTheGuru
2 hours ago





it basically is a list that serves as a value to the key color @Praind

– KaanTheGuru
2 hours ago













Is it necessary to have a string instead of a list if there's only one element?

– Praind
1 hour ago





Is it necessary to have a string instead of a list if there's only one element?

– Praind
1 hour ago













yes it is necessary, will edit question to include that detail. Thank you @Praind

– KaanTheGuru
1 hour ago





yes it is necessary, will edit question to include that detail. Thank you @Praind

– KaanTheGuru
1 hour ago












4 Answers
4






active

oldest

votes


















9














Using pure python, you can do insert into an OrderedDict to retain insertion order:



from collections import OrderedDict

d = OrderedDict()
for l in lst:
d.setdefault((l['number'], l['favorite']), set()).add(l['color'])

[{'number': k[0], 'favorite': k[1], 'color': v.pop() if len(v) == 1 else v}
for k, v in d.items()]
# [{'color': {'green', 'red'}, 'favorite': False, 'number': 1},
# {'color': 'red', 'favorite': True, 'number': 1},
# {'color': 'red', 'favorite': False, 'number': 2}]




This can also be done quite easily using the pandas GroupBy API:



import pandas as pd

d = (pd.DataFrame(lst)
.groupby(['number', 'favorite'])
.color
.agg(set)
.reset_index()
.to_dict('r'))
d
# [{'color': {'green', 'red'}, 'favorite': False, 'number': 1},
# {'color': {'red'}, 'favorite': True, 'number': 1},
# {'color': {'red'}, 'favorite': False, 'number': 2}]


If the condition of a string for a single element is required, you can use



[{'color': (lambda v: v.pop() if len(v) == 1 else v)(d_.pop('color')), **d_} 
for d_ in d]
# [{'color': {'green', 'red'}, 'favorite': False, 'number': 1},
# {'color': 'red', 'favorite': True, 'number': 1},
# {'color': 'red', 'favorite': False, 'number': 2}]





share|improve this answer

































    2














    A solution in pure Python would be to use a defaultdict with a composite key. You could use that to merge your values.
    Afterwards you can create a list again out of that dictionary.



    from collections import defaultdict

    dct = defaultdict()

    for entry in lst:
    dct[(entry['number'], entry['favorite'])].append(entry['color'])

    lst = [{'number': key[0], 'favorite': key[1], color: value if len(value) > 1 else value[0]}
    for key, value in dct.items()]





    share|improve this answer


























    • *composite key i guess?

      – Vineeth Sai
      1 hour ago











    • @Vineeth Sai Indeed ;)

      – Praind
      1 hour ago











    • would this work even if there are more keys than the three mentioned, i.ei if you have a new key? @Praind

      – KaanTheGuru
      1 hour ago








    • 1





      Of course, you just have to add them to the composite key. E.g. dct[(entry['number'], entry['favorite'], entry['otherKey'])].append(entry['color'])

      – Praind
      1 hour ago



















    2














    Or groupby of itertools:



    import itertools
    lst = [
    {'number': 1, 'favorite': False, 'color': 'red'},
    {'number': 1, 'favorite': False, 'color': 'green'},
    {'number': 1, 'favorite': False, 'color': 'red'},
    {'number': 1, 'favorite': True, 'color': 'red'},
    {'number': 2, 'favorite': False, 'color': 'red'}]
    l=[list(y) for x,y in itertools.groupby(sorted(lst,key=lambda x: (x['number'],x['favorite'])),lambda x: (x['number'],x['favorite']))]
    print([{k:(v if k!='color' else list(set([x['color'] for x in i]))) for k,v in i[0].items()} for i in l])


    Output:



    [{'number': 1, 'favorite': False, 'color': ['green', 'red']}, {'number': 1, 'favorite': True, 'color': ['red']}, {'number': 2, 'favorite': False, 'color': ['red']}]





    share|improve this answer





















    • 1





      Do you know that your solution won't work if the input list isn't already sorted (w.r.t. number and favorite)? Like if the list contained first dict element as number=1, and favorite=False, second as number=1, and favorite=True, and then number=1, and favorite=False.

      – Muhammad Ahmad
      1 hour ago






    • 1





      Try with this input list: lst = [ {'number': 1, 'favorite': False, 'color': 'red'}, {'number': 1, 'favorite': True, 'color': 'red'}, {'number': 1, 'favorite': False, 'color': 'green'}, {'number': 1, 'favorite': False, 'color': 'red'}, {'number': 2, 'favorite': False, 'color': 'red'}]

      – Muhammad Ahmad
      1 hour ago











    • @MuhammadAhmad I edited my answer, sorry.

      – U9-Forward
      53 mins ago



















    0














    Here's one way to do it,



    I've built a dict first using a tuple as a composite key, Then made a new list out of that dict. You can write comprehensions to further reduce lines and optimize it, Hope it helps.



    new_dict = {}

    for item in lst:
    try: # if already exists then append to the list
    new_dict.get((item['number'], item['favorite']))
    new_dict[(item['number'], item['favorite'])].append(item['color'])
    except KeyError: # if it doesn't then create a new entry to that key
    new_dict[(item['number'], item['favorite'])] = [item['color']]


    final_list =
    for k, v in new_dict.items(): # keep appending dicts to our list
    final_list.append({'number': k[0], 'favorite': k[1], 'color':set(v)})

    print(final_list)


    Outputs:



    [{'number': 1, 'favorite': False, 'color': {'green', 'red'}}, {'number': 1, 'favorite': True, 'color': {'red'}}, {'number': 2, 'favorite': False, 'color': {'red'}}]





    share|improve this answer























      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',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54248936%2fmerge-a-dict-element-in-a-list-of-dicts-using-python%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      9














      Using pure python, you can do insert into an OrderedDict to retain insertion order:



      from collections import OrderedDict

      d = OrderedDict()
      for l in lst:
      d.setdefault((l['number'], l['favorite']), set()).add(l['color'])

      [{'number': k[0], 'favorite': k[1], 'color': v.pop() if len(v) == 1 else v}
      for k, v in d.items()]
      # [{'color': {'green', 'red'}, 'favorite': False, 'number': 1},
      # {'color': 'red', 'favorite': True, 'number': 1},
      # {'color': 'red', 'favorite': False, 'number': 2}]




      This can also be done quite easily using the pandas GroupBy API:



      import pandas as pd

      d = (pd.DataFrame(lst)
      .groupby(['number', 'favorite'])
      .color
      .agg(set)
      .reset_index()
      .to_dict('r'))
      d
      # [{'color': {'green', 'red'}, 'favorite': False, 'number': 1},
      # {'color': {'red'}, 'favorite': True, 'number': 1},
      # {'color': {'red'}, 'favorite': False, 'number': 2}]


      If the condition of a string for a single element is required, you can use



      [{'color': (lambda v: v.pop() if len(v) == 1 else v)(d_.pop('color')), **d_} 
      for d_ in d]
      # [{'color': {'green', 'red'}, 'favorite': False, 'number': 1},
      # {'color': 'red', 'favorite': True, 'number': 1},
      # {'color': 'red', 'favorite': False, 'number': 2}]





      share|improve this answer






























        9














        Using pure python, you can do insert into an OrderedDict to retain insertion order:



        from collections import OrderedDict

        d = OrderedDict()
        for l in lst:
        d.setdefault((l['number'], l['favorite']), set()).add(l['color'])

        [{'number': k[0], 'favorite': k[1], 'color': v.pop() if len(v) == 1 else v}
        for k, v in d.items()]
        # [{'color': {'green', 'red'}, 'favorite': False, 'number': 1},
        # {'color': 'red', 'favorite': True, 'number': 1},
        # {'color': 'red', 'favorite': False, 'number': 2}]




        This can also be done quite easily using the pandas GroupBy API:



        import pandas as pd

        d = (pd.DataFrame(lst)
        .groupby(['number', 'favorite'])
        .color
        .agg(set)
        .reset_index()
        .to_dict('r'))
        d
        # [{'color': {'green', 'red'}, 'favorite': False, 'number': 1},
        # {'color': {'red'}, 'favorite': True, 'number': 1},
        # {'color': {'red'}, 'favorite': False, 'number': 2}]


        If the condition of a string for a single element is required, you can use



        [{'color': (lambda v: v.pop() if len(v) == 1 else v)(d_.pop('color')), **d_} 
        for d_ in d]
        # [{'color': {'green', 'red'}, 'favorite': False, 'number': 1},
        # {'color': 'red', 'favorite': True, 'number': 1},
        # {'color': 'red', 'favorite': False, 'number': 2}]





        share|improve this answer




























          9












          9








          9







          Using pure python, you can do insert into an OrderedDict to retain insertion order:



          from collections import OrderedDict

          d = OrderedDict()
          for l in lst:
          d.setdefault((l['number'], l['favorite']), set()).add(l['color'])

          [{'number': k[0], 'favorite': k[1], 'color': v.pop() if len(v) == 1 else v}
          for k, v in d.items()]
          # [{'color': {'green', 'red'}, 'favorite': False, 'number': 1},
          # {'color': 'red', 'favorite': True, 'number': 1},
          # {'color': 'red', 'favorite': False, 'number': 2}]




          This can also be done quite easily using the pandas GroupBy API:



          import pandas as pd

          d = (pd.DataFrame(lst)
          .groupby(['number', 'favorite'])
          .color
          .agg(set)
          .reset_index()
          .to_dict('r'))
          d
          # [{'color': {'green', 'red'}, 'favorite': False, 'number': 1},
          # {'color': {'red'}, 'favorite': True, 'number': 1},
          # {'color': {'red'}, 'favorite': False, 'number': 2}]


          If the condition of a string for a single element is required, you can use



          [{'color': (lambda v: v.pop() if len(v) == 1 else v)(d_.pop('color')), **d_} 
          for d_ in d]
          # [{'color': {'green', 'red'}, 'favorite': False, 'number': 1},
          # {'color': 'red', 'favorite': True, 'number': 1},
          # {'color': 'red', 'favorite': False, 'number': 2}]





          share|improve this answer















          Using pure python, you can do insert into an OrderedDict to retain insertion order:



          from collections import OrderedDict

          d = OrderedDict()
          for l in lst:
          d.setdefault((l['number'], l['favorite']), set()).add(l['color'])

          [{'number': k[0], 'favorite': k[1], 'color': v.pop() if len(v) == 1 else v}
          for k, v in d.items()]
          # [{'color': {'green', 'red'}, 'favorite': False, 'number': 1},
          # {'color': 'red', 'favorite': True, 'number': 1},
          # {'color': 'red', 'favorite': False, 'number': 2}]




          This can also be done quite easily using the pandas GroupBy API:



          import pandas as pd

          d = (pd.DataFrame(lst)
          .groupby(['number', 'favorite'])
          .color
          .agg(set)
          .reset_index()
          .to_dict('r'))
          d
          # [{'color': {'green', 'red'}, 'favorite': False, 'number': 1},
          # {'color': {'red'}, 'favorite': True, 'number': 1},
          # {'color': {'red'}, 'favorite': False, 'number': 2}]


          If the condition of a string for a single element is required, you can use



          [{'color': (lambda v: v.pop() if len(v) == 1 else v)(d_.pop('color')), **d_} 
          for d_ in d]
          # [{'color': {'green', 'red'}, 'favorite': False, 'number': 1},
          # {'color': 'red', 'favorite': True, 'number': 1},
          # {'color': 'red', 'favorite': False, 'number': 2}]






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 1 hour ago

























          answered 1 hour ago









          coldspeedcoldspeed

          125k22125209




          125k22125209

























              2














              A solution in pure Python would be to use a defaultdict with a composite key. You could use that to merge your values.
              Afterwards you can create a list again out of that dictionary.



              from collections import defaultdict

              dct = defaultdict()

              for entry in lst:
              dct[(entry['number'], entry['favorite'])].append(entry['color'])

              lst = [{'number': key[0], 'favorite': key[1], color: value if len(value) > 1 else value[0]}
              for key, value in dct.items()]





              share|improve this answer


























              • *composite key i guess?

                – Vineeth Sai
                1 hour ago











              • @Vineeth Sai Indeed ;)

                – Praind
                1 hour ago











              • would this work even if there are more keys than the three mentioned, i.ei if you have a new key? @Praind

                – KaanTheGuru
                1 hour ago








              • 1





                Of course, you just have to add them to the composite key. E.g. dct[(entry['number'], entry['favorite'], entry['otherKey'])].append(entry['color'])

                – Praind
                1 hour ago
















              2














              A solution in pure Python would be to use a defaultdict with a composite key. You could use that to merge your values.
              Afterwards you can create a list again out of that dictionary.



              from collections import defaultdict

              dct = defaultdict()

              for entry in lst:
              dct[(entry['number'], entry['favorite'])].append(entry['color'])

              lst = [{'number': key[0], 'favorite': key[1], color: value if len(value) > 1 else value[0]}
              for key, value in dct.items()]





              share|improve this answer


























              • *composite key i guess?

                – Vineeth Sai
                1 hour ago











              • @Vineeth Sai Indeed ;)

                – Praind
                1 hour ago











              • would this work even if there are more keys than the three mentioned, i.ei if you have a new key? @Praind

                – KaanTheGuru
                1 hour ago








              • 1





                Of course, you just have to add them to the composite key. E.g. dct[(entry['number'], entry['favorite'], entry['otherKey'])].append(entry['color'])

                – Praind
                1 hour ago














              2












              2








              2







              A solution in pure Python would be to use a defaultdict with a composite key. You could use that to merge your values.
              Afterwards you can create a list again out of that dictionary.



              from collections import defaultdict

              dct = defaultdict()

              for entry in lst:
              dct[(entry['number'], entry['favorite'])].append(entry['color'])

              lst = [{'number': key[0], 'favorite': key[1], color: value if len(value) > 1 else value[0]}
              for key, value in dct.items()]





              share|improve this answer















              A solution in pure Python would be to use a defaultdict with a composite key. You could use that to merge your values.
              Afterwards you can create a list again out of that dictionary.



              from collections import defaultdict

              dct = defaultdict()

              for entry in lst:
              dct[(entry['number'], entry['favorite'])].append(entry['color'])

              lst = [{'number': key[0], 'favorite': key[1], color: value if len(value) > 1 else value[0]}
              for key, value in dct.items()]






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited 1 hour ago

























              answered 1 hour ago









              PraindPraind

              874718




              874718













              • *composite key i guess?

                – Vineeth Sai
                1 hour ago











              • @Vineeth Sai Indeed ;)

                – Praind
                1 hour ago











              • would this work even if there are more keys than the three mentioned, i.ei if you have a new key? @Praind

                – KaanTheGuru
                1 hour ago








              • 1





                Of course, you just have to add them to the composite key. E.g. dct[(entry['number'], entry['favorite'], entry['otherKey'])].append(entry['color'])

                – Praind
                1 hour ago



















              • *composite key i guess?

                – Vineeth Sai
                1 hour ago











              • @Vineeth Sai Indeed ;)

                – Praind
                1 hour ago











              • would this work even if there are more keys than the three mentioned, i.ei if you have a new key? @Praind

                – KaanTheGuru
                1 hour ago








              • 1





                Of course, you just have to add them to the composite key. E.g. dct[(entry['number'], entry['favorite'], entry['otherKey'])].append(entry['color'])

                – Praind
                1 hour ago

















              *composite key i guess?

              – Vineeth Sai
              1 hour ago





              *composite key i guess?

              – Vineeth Sai
              1 hour ago













              @Vineeth Sai Indeed ;)

              – Praind
              1 hour ago





              @Vineeth Sai Indeed ;)

              – Praind
              1 hour ago













              would this work even if there are more keys than the three mentioned, i.ei if you have a new key? @Praind

              – KaanTheGuru
              1 hour ago







              would this work even if there are more keys than the three mentioned, i.ei if you have a new key? @Praind

              – KaanTheGuru
              1 hour ago






              1




              1





              Of course, you just have to add them to the composite key. E.g. dct[(entry['number'], entry['favorite'], entry['otherKey'])].append(entry['color'])

              – Praind
              1 hour ago





              Of course, you just have to add them to the composite key. E.g. dct[(entry['number'], entry['favorite'], entry['otherKey'])].append(entry['color'])

              – Praind
              1 hour ago











              2














              Or groupby of itertools:



              import itertools
              lst = [
              {'number': 1, 'favorite': False, 'color': 'red'},
              {'number': 1, 'favorite': False, 'color': 'green'},
              {'number': 1, 'favorite': False, 'color': 'red'},
              {'number': 1, 'favorite': True, 'color': 'red'},
              {'number': 2, 'favorite': False, 'color': 'red'}]
              l=[list(y) for x,y in itertools.groupby(sorted(lst,key=lambda x: (x['number'],x['favorite'])),lambda x: (x['number'],x['favorite']))]
              print([{k:(v if k!='color' else list(set([x['color'] for x in i]))) for k,v in i[0].items()} for i in l])


              Output:



              [{'number': 1, 'favorite': False, 'color': ['green', 'red']}, {'number': 1, 'favorite': True, 'color': ['red']}, {'number': 2, 'favorite': False, 'color': ['red']}]





              share|improve this answer





















              • 1





                Do you know that your solution won't work if the input list isn't already sorted (w.r.t. number and favorite)? Like if the list contained first dict element as number=1, and favorite=False, second as number=1, and favorite=True, and then number=1, and favorite=False.

                – Muhammad Ahmad
                1 hour ago






              • 1





                Try with this input list: lst = [ {'number': 1, 'favorite': False, 'color': 'red'}, {'number': 1, 'favorite': True, 'color': 'red'}, {'number': 1, 'favorite': False, 'color': 'green'}, {'number': 1, 'favorite': False, 'color': 'red'}, {'number': 2, 'favorite': False, 'color': 'red'}]

                – Muhammad Ahmad
                1 hour ago











              • @MuhammadAhmad I edited my answer, sorry.

                – U9-Forward
                53 mins ago
















              2














              Or groupby of itertools:



              import itertools
              lst = [
              {'number': 1, 'favorite': False, 'color': 'red'},
              {'number': 1, 'favorite': False, 'color': 'green'},
              {'number': 1, 'favorite': False, 'color': 'red'},
              {'number': 1, 'favorite': True, 'color': 'red'},
              {'number': 2, 'favorite': False, 'color': 'red'}]
              l=[list(y) for x,y in itertools.groupby(sorted(lst,key=lambda x: (x['number'],x['favorite'])),lambda x: (x['number'],x['favorite']))]
              print([{k:(v if k!='color' else list(set([x['color'] for x in i]))) for k,v in i[0].items()} for i in l])


              Output:



              [{'number': 1, 'favorite': False, 'color': ['green', 'red']}, {'number': 1, 'favorite': True, 'color': ['red']}, {'number': 2, 'favorite': False, 'color': ['red']}]





              share|improve this answer





















              • 1





                Do you know that your solution won't work if the input list isn't already sorted (w.r.t. number and favorite)? Like if the list contained first dict element as number=1, and favorite=False, second as number=1, and favorite=True, and then number=1, and favorite=False.

                – Muhammad Ahmad
                1 hour ago






              • 1





                Try with this input list: lst = [ {'number': 1, 'favorite': False, 'color': 'red'}, {'number': 1, 'favorite': True, 'color': 'red'}, {'number': 1, 'favorite': False, 'color': 'green'}, {'number': 1, 'favorite': False, 'color': 'red'}, {'number': 2, 'favorite': False, 'color': 'red'}]

                – Muhammad Ahmad
                1 hour ago











              • @MuhammadAhmad I edited my answer, sorry.

                – U9-Forward
                53 mins ago














              2












              2








              2







              Or groupby of itertools:



              import itertools
              lst = [
              {'number': 1, 'favorite': False, 'color': 'red'},
              {'number': 1, 'favorite': False, 'color': 'green'},
              {'number': 1, 'favorite': False, 'color': 'red'},
              {'number': 1, 'favorite': True, 'color': 'red'},
              {'number': 2, 'favorite': False, 'color': 'red'}]
              l=[list(y) for x,y in itertools.groupby(sorted(lst,key=lambda x: (x['number'],x['favorite'])),lambda x: (x['number'],x['favorite']))]
              print([{k:(v if k!='color' else list(set([x['color'] for x in i]))) for k,v in i[0].items()} for i in l])


              Output:



              [{'number': 1, 'favorite': False, 'color': ['green', 'red']}, {'number': 1, 'favorite': True, 'color': ['red']}, {'number': 2, 'favorite': False, 'color': ['red']}]





              share|improve this answer















              Or groupby of itertools:



              import itertools
              lst = [
              {'number': 1, 'favorite': False, 'color': 'red'},
              {'number': 1, 'favorite': False, 'color': 'green'},
              {'number': 1, 'favorite': False, 'color': 'red'},
              {'number': 1, 'favorite': True, 'color': 'red'},
              {'number': 2, 'favorite': False, 'color': 'red'}]
              l=[list(y) for x,y in itertools.groupby(sorted(lst,key=lambda x: (x['number'],x['favorite'])),lambda x: (x['number'],x['favorite']))]
              print([{k:(v if k!='color' else list(set([x['color'] for x in i]))) for k,v in i[0].items()} for i in l])


              Output:



              [{'number': 1, 'favorite': False, 'color': ['green', 'red']}, {'number': 1, 'favorite': True, 'color': ['red']}, {'number': 2, 'favorite': False, 'color': ['red']}]






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited 53 mins ago

























              answered 1 hour ago









              U9-ForwardU9-Forward

              14.1k21337




              14.1k21337








              • 1





                Do you know that your solution won't work if the input list isn't already sorted (w.r.t. number and favorite)? Like if the list contained first dict element as number=1, and favorite=False, second as number=1, and favorite=True, and then number=1, and favorite=False.

                – Muhammad Ahmad
                1 hour ago






              • 1





                Try with this input list: lst = [ {'number': 1, 'favorite': False, 'color': 'red'}, {'number': 1, 'favorite': True, 'color': 'red'}, {'number': 1, 'favorite': False, 'color': 'green'}, {'number': 1, 'favorite': False, 'color': 'red'}, {'number': 2, 'favorite': False, 'color': 'red'}]

                – Muhammad Ahmad
                1 hour ago











              • @MuhammadAhmad I edited my answer, sorry.

                – U9-Forward
                53 mins ago














              • 1





                Do you know that your solution won't work if the input list isn't already sorted (w.r.t. number and favorite)? Like if the list contained first dict element as number=1, and favorite=False, second as number=1, and favorite=True, and then number=1, and favorite=False.

                – Muhammad Ahmad
                1 hour ago






              • 1





                Try with this input list: lst = [ {'number': 1, 'favorite': False, 'color': 'red'}, {'number': 1, 'favorite': True, 'color': 'red'}, {'number': 1, 'favorite': False, 'color': 'green'}, {'number': 1, 'favorite': False, 'color': 'red'}, {'number': 2, 'favorite': False, 'color': 'red'}]

                – Muhammad Ahmad
                1 hour ago











              • @MuhammadAhmad I edited my answer, sorry.

                – U9-Forward
                53 mins ago








              1




              1





              Do you know that your solution won't work if the input list isn't already sorted (w.r.t. number and favorite)? Like if the list contained first dict element as number=1, and favorite=False, second as number=1, and favorite=True, and then number=1, and favorite=False.

              – Muhammad Ahmad
              1 hour ago





              Do you know that your solution won't work if the input list isn't already sorted (w.r.t. number and favorite)? Like if the list contained first dict element as number=1, and favorite=False, second as number=1, and favorite=True, and then number=1, and favorite=False.

              – Muhammad Ahmad
              1 hour ago




              1




              1





              Try with this input list: lst = [ {'number': 1, 'favorite': False, 'color': 'red'}, {'number': 1, 'favorite': True, 'color': 'red'}, {'number': 1, 'favorite': False, 'color': 'green'}, {'number': 1, 'favorite': False, 'color': 'red'}, {'number': 2, 'favorite': False, 'color': 'red'}]

              – Muhammad Ahmad
              1 hour ago





              Try with this input list: lst = [ {'number': 1, 'favorite': False, 'color': 'red'}, {'number': 1, 'favorite': True, 'color': 'red'}, {'number': 1, 'favorite': False, 'color': 'green'}, {'number': 1, 'favorite': False, 'color': 'red'}, {'number': 2, 'favorite': False, 'color': 'red'}]

              – Muhammad Ahmad
              1 hour ago













              @MuhammadAhmad I edited my answer, sorry.

              – U9-Forward
              53 mins ago





              @MuhammadAhmad I edited my answer, sorry.

              – U9-Forward
              53 mins ago











              0














              Here's one way to do it,



              I've built a dict first using a tuple as a composite key, Then made a new list out of that dict. You can write comprehensions to further reduce lines and optimize it, Hope it helps.



              new_dict = {}

              for item in lst:
              try: # if already exists then append to the list
              new_dict.get((item['number'], item['favorite']))
              new_dict[(item['number'], item['favorite'])].append(item['color'])
              except KeyError: # if it doesn't then create a new entry to that key
              new_dict[(item['number'], item['favorite'])] = [item['color']]


              final_list =
              for k, v in new_dict.items(): # keep appending dicts to our list
              final_list.append({'number': k[0], 'favorite': k[1], 'color':set(v)})

              print(final_list)


              Outputs:



              [{'number': 1, 'favorite': False, 'color': {'green', 'red'}}, {'number': 1, 'favorite': True, 'color': {'red'}}, {'number': 2, 'favorite': False, 'color': {'red'}}]





              share|improve this answer




























                0














                Here's one way to do it,



                I've built a dict first using a tuple as a composite key, Then made a new list out of that dict. You can write comprehensions to further reduce lines and optimize it, Hope it helps.



                new_dict = {}

                for item in lst:
                try: # if already exists then append to the list
                new_dict.get((item['number'], item['favorite']))
                new_dict[(item['number'], item['favorite'])].append(item['color'])
                except KeyError: # if it doesn't then create a new entry to that key
                new_dict[(item['number'], item['favorite'])] = [item['color']]


                final_list =
                for k, v in new_dict.items(): # keep appending dicts to our list
                final_list.append({'number': k[0], 'favorite': k[1], 'color':set(v)})

                print(final_list)


                Outputs:



                [{'number': 1, 'favorite': False, 'color': {'green', 'red'}}, {'number': 1, 'favorite': True, 'color': {'red'}}, {'number': 2, 'favorite': False, 'color': {'red'}}]





                share|improve this answer


























                  0












                  0








                  0







                  Here's one way to do it,



                  I've built a dict first using a tuple as a composite key, Then made a new list out of that dict. You can write comprehensions to further reduce lines and optimize it, Hope it helps.



                  new_dict = {}

                  for item in lst:
                  try: # if already exists then append to the list
                  new_dict.get((item['number'], item['favorite']))
                  new_dict[(item['number'], item['favorite'])].append(item['color'])
                  except KeyError: # if it doesn't then create a new entry to that key
                  new_dict[(item['number'], item['favorite'])] = [item['color']]


                  final_list =
                  for k, v in new_dict.items(): # keep appending dicts to our list
                  final_list.append({'number': k[0], 'favorite': k[1], 'color':set(v)})

                  print(final_list)


                  Outputs:



                  [{'number': 1, 'favorite': False, 'color': {'green', 'red'}}, {'number': 1, 'favorite': True, 'color': {'red'}}, {'number': 2, 'favorite': False, 'color': {'red'}}]





                  share|improve this answer













                  Here's one way to do it,



                  I've built a dict first using a tuple as a composite key, Then made a new list out of that dict. You can write comprehensions to further reduce lines and optimize it, Hope it helps.



                  new_dict = {}

                  for item in lst:
                  try: # if already exists then append to the list
                  new_dict.get((item['number'], item['favorite']))
                  new_dict[(item['number'], item['favorite'])].append(item['color'])
                  except KeyError: # if it doesn't then create a new entry to that key
                  new_dict[(item['number'], item['favorite'])] = [item['color']]


                  final_list =
                  for k, v in new_dict.items(): # keep appending dicts to our list
                  final_list.append({'number': k[0], 'favorite': k[1], 'color':set(v)})

                  print(final_list)


                  Outputs:



                  [{'number': 1, 'favorite': False, 'color': {'green', 'red'}}, {'number': 1, 'favorite': True, 'color': {'red'}}, {'number': 2, 'favorite': False, 'color': {'red'}}]






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered 1 hour ago









                  Vineeth SaiVineeth Sai

                  2,49051124




                  2,49051124






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54248936%2fmerge-a-dict-element-in-a-list-of-dicts-using-python%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Polycentropodidae

                      Magento 2 Error message: Invalid state change requested

                      Paulmy