Group and aggregate a list of dictionaries by multiple keys

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












13















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
    Jan 18 at 6:53











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

    – Praind
    Jan 18 at 6:53











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

    – KaanTheGuru
    Jan 18 at 6:55











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

    – Praind
    Jan 18 at 6:58











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

    – KaanTheGuru
    Jan 18 at 7:01















13















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
    Jan 18 at 6:53











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

    – Praind
    Jan 18 at 6:53











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

    – KaanTheGuru
    Jan 18 at 6:55











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

    – Praind
    Jan 18 at 6:58











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

    – KaanTheGuru
    Jan 18 at 7:01













13












13








13








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 Jan 18 at 9:39









coldspeed

129k23132218




129k23132218










asked Jan 18 at 6:45









KaanTheGuruKaanTheGuru

859




859












  • Are you interested in using pandas for this?

    – coldspeed
    Jan 18 at 6:53











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

    – Praind
    Jan 18 at 6:53











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

    – KaanTheGuru
    Jan 18 at 6:55











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

    – Praind
    Jan 18 at 6:58











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

    – KaanTheGuru
    Jan 18 at 7:01

















  • Are you interested in using pandas for this?

    – coldspeed
    Jan 18 at 6:53











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

    – Praind
    Jan 18 at 6:53











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

    – KaanTheGuru
    Jan 18 at 6:55











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

    – Praind
    Jan 18 at 6:58











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

    – KaanTheGuru
    Jan 18 at 7:01
















Are you interested in using pandas for this?

– coldspeed
Jan 18 at 6:53





Are you interested in using pandas for this?

– coldspeed
Jan 18 at 6:53













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

– Praind
Jan 18 at 6:53





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

– Praind
Jan 18 at 6:53













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

– KaanTheGuru
Jan 18 at 6:55





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

– KaanTheGuru
Jan 18 at 6:55













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

– Praind
Jan 18 at 6:58





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

– Praind
Jan 18 at 6:58













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

– KaanTheGuru
Jan 18 at 7:01





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

– KaanTheGuru
Jan 18 at 7:01












6 Answers
6






active

oldest

votes


















14














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
































    3














    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
      Jan 18 at 7:13











    • @Vineeth Sai Indeed ;)

      – Praind
      Jan 18 at 7:14











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

      – KaanTheGuru
      Jan 18 at 7:16







    • 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
      Jan 18 at 7:19











    • This would not retain order (unless python3.6), as the question seems to require.

      – coldspeed
      Jan 18 at 9:41



















    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
      Jan 18 at 7:34






    • 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
      Jan 18 at 7:34


















    1














    You can use an ordered dictionary with default set values.1 Then iterate your list of dictionaries, using (number, favorite) as keys. This works since tuples are hashable and therefore permitted to be used as dictionary keys.



    It's good practice to use a consistent structure. So, instead of having strings for single values and sets for multiple, use sets throughout:



    from collections import OrderedDict, defaultdict

    class DefaultOrderedDict(OrderedDict):
    def __missing__(self, k):
    self[k] = set()
    return self[k]

    d = DefaultOrderedDict() # Python 3.7+: d = defaultdict(set)

    for i in lst:
    d[(i['number'], i['favorite'])].add(i['color'])

    res = ['number': num, 'favorite': fav, 'color': col for (num, fav), col in d.items()]

    print(res)
    # ['color': 'green', 'red', 'favorite': False, 'number': 1,
    # 'color': 'red', 'favorite': True, 'number': 1,
    # 'color': 'red', 'favorite': False, 'number': 2]


    If you insist on having different types depending on number of colours, you can redefine the list comprehension to use a ternary statement:



    res = ['number': num, 'favorite': fav, 'color': next(iter(col)) if len(col) == 1 else col 
    for (num, fav), col in d.items()]

    print(res)
    # ['color': 'green', 'red', 'favorite': False, 'number': 1,
    # 'color': 'red', 'favorite': True, 'number': 1,
    # 'color': 'red', 'favorite': False, 'number': 2]



    1 The point is noteworthy in Python versions prior to 3.7, where dictionaries are not guaranteed to be insertion ordered. With Python 3.7+, you can take advantage of insertion ordering and just use dict or a subclass of dict such as collections.defaultdict.






    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














        A friend of mine made the following function to solve this problem, without using any external libraries:



        def uniqifyColors(l):
        for elem in l:
        for item in l:
        if elem['number'] == item['number'] and elem['favorite'] == item['favorite']:
        for clr in item['color']:
        if clr not in elem['color']:
        elem['color'].append(clr)
        return l


        After using this Python function, he simply did a trivial uniqify to get the unique results from the list. It does not, however, keep a single color as a string, but rather a list with a single element.






        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%2fgroup-and-aggregate-a-list-of-dictionaries-by-multiple-keys%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          6 Answers
          6






          active

          oldest

          votes








          6 Answers
          6






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          14














          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





























            14














            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



























              14












              14








              14







              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 Jan 18 at 7:10

























              answered Jan 18 at 6:56









              coldspeedcoldspeed

              129k23132218




              129k23132218























                  3














                  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
                    Jan 18 at 7:13











                  • @Vineeth Sai Indeed ;)

                    – Praind
                    Jan 18 at 7:14











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

                    – KaanTheGuru
                    Jan 18 at 7:16







                  • 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
                    Jan 18 at 7:19











                  • This would not retain order (unless python3.6), as the question seems to require.

                    – coldspeed
                    Jan 18 at 9:41
















                  3














                  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
                    Jan 18 at 7:13











                  • @Vineeth Sai Indeed ;)

                    – Praind
                    Jan 18 at 7:14











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

                    – KaanTheGuru
                    Jan 18 at 7:16







                  • 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
                    Jan 18 at 7:19











                  • This would not retain order (unless python3.6), as the question seems to require.

                    – coldspeed
                    Jan 18 at 9:41














                  3












                  3








                  3







                  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 Jan 18 at 7:14

























                  answered Jan 18 at 7:12









                  PraindPraind

                  936719




                  936719












                  • *composite key i guess?

                    – Vineeth Sai
                    Jan 18 at 7:13











                  • @Vineeth Sai Indeed ;)

                    – Praind
                    Jan 18 at 7:14











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

                    – KaanTheGuru
                    Jan 18 at 7:16







                  • 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
                    Jan 18 at 7:19











                  • This would not retain order (unless python3.6), as the question seems to require.

                    – coldspeed
                    Jan 18 at 9:41


















                  • *composite key i guess?

                    – Vineeth Sai
                    Jan 18 at 7:13











                  • @Vineeth Sai Indeed ;)

                    – Praind
                    Jan 18 at 7:14











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

                    – KaanTheGuru
                    Jan 18 at 7:16







                  • 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
                    Jan 18 at 7:19











                  • This would not retain order (unless python3.6), as the question seems to require.

                    – coldspeed
                    Jan 18 at 9:41

















                  *composite key i guess?

                  – Vineeth Sai
                  Jan 18 at 7:13





                  *composite key i guess?

                  – Vineeth Sai
                  Jan 18 at 7:13













                  @Vineeth Sai Indeed ;)

                  – Praind
                  Jan 18 at 7:14





                  @Vineeth Sai Indeed ;)

                  – Praind
                  Jan 18 at 7:14













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

                  – KaanTheGuru
                  Jan 18 at 7:16






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

                  – KaanTheGuru
                  Jan 18 at 7:16





                  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
                  Jan 18 at 7:19





                  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
                  Jan 18 at 7:19













                  This would not retain order (unless python3.6), as the question seems to require.

                  – coldspeed
                  Jan 18 at 9:41






                  This would not retain order (unless python3.6), as the question seems to require.

                  – coldspeed
                  Jan 18 at 9:41












                  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
                    Jan 18 at 7:34






                  • 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
                    Jan 18 at 7:34















                  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
                    Jan 18 at 7:34






                  • 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
                    Jan 18 at 7:34













                  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 Jan 18 at 8:02

























                  answered Jan 18 at 7:18









                  U9-ForwardU9-Forward

                  14.8k31338




                  14.8k31338







                  • 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
                    Jan 18 at 7:34






                  • 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
                    Jan 18 at 7:34












                  • 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
                    Jan 18 at 7:34






                  • 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
                    Jan 18 at 7:34







                  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
                  Jan 18 at 7:34





                  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
                  Jan 18 at 7:34




                  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
                  Jan 18 at 7:34





                  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
                  Jan 18 at 7:34











                  1














                  You can use an ordered dictionary with default set values.1 Then iterate your list of dictionaries, using (number, favorite) as keys. This works since tuples are hashable and therefore permitted to be used as dictionary keys.



                  It's good practice to use a consistent structure. So, instead of having strings for single values and sets for multiple, use sets throughout:



                  from collections import OrderedDict, defaultdict

                  class DefaultOrderedDict(OrderedDict):
                  def __missing__(self, k):
                  self[k] = set()
                  return self[k]

                  d = DefaultOrderedDict() # Python 3.7+: d = defaultdict(set)

                  for i in lst:
                  d[(i['number'], i['favorite'])].add(i['color'])

                  res = ['number': num, 'favorite': fav, 'color': col for (num, fav), col in d.items()]

                  print(res)
                  # ['color': 'green', 'red', 'favorite': False, 'number': 1,
                  # 'color': 'red', 'favorite': True, 'number': 1,
                  # 'color': 'red', 'favorite': False, 'number': 2]


                  If you insist on having different types depending on number of colours, you can redefine the list comprehension to use a ternary statement:



                  res = ['number': num, 'favorite': fav, 'color': next(iter(col)) if len(col) == 1 else col 
                  for (num, fav), col in d.items()]

                  print(res)
                  # ['color': 'green', 'red', 'favorite': False, 'number': 1,
                  # 'color': 'red', 'favorite': True, 'number': 1,
                  # 'color': 'red', 'favorite': False, 'number': 2]



                  1 The point is noteworthy in Python versions prior to 3.7, where dictionaries are not guaranteed to be insertion ordered. With Python 3.7+, you can take advantage of insertion ordering and just use dict or a subclass of dict such as collections.defaultdict.






                  share|improve this answer



























                    1














                    You can use an ordered dictionary with default set values.1 Then iterate your list of dictionaries, using (number, favorite) as keys. This works since tuples are hashable and therefore permitted to be used as dictionary keys.



                    It's good practice to use a consistent structure. So, instead of having strings for single values and sets for multiple, use sets throughout:



                    from collections import OrderedDict, defaultdict

                    class DefaultOrderedDict(OrderedDict):
                    def __missing__(self, k):
                    self[k] = set()
                    return self[k]

                    d = DefaultOrderedDict() # Python 3.7+: d = defaultdict(set)

                    for i in lst:
                    d[(i['number'], i['favorite'])].add(i['color'])

                    res = ['number': num, 'favorite': fav, 'color': col for (num, fav), col in d.items()]

                    print(res)
                    # ['color': 'green', 'red', 'favorite': False, 'number': 1,
                    # 'color': 'red', 'favorite': True, 'number': 1,
                    # 'color': 'red', 'favorite': False, 'number': 2]


                    If you insist on having different types depending on number of colours, you can redefine the list comprehension to use a ternary statement:



                    res = ['number': num, 'favorite': fav, 'color': next(iter(col)) if len(col) == 1 else col 
                    for (num, fav), col in d.items()]

                    print(res)
                    # ['color': 'green', 'red', 'favorite': False, 'number': 1,
                    # 'color': 'red', 'favorite': True, 'number': 1,
                    # 'color': 'red', 'favorite': False, 'number': 2]



                    1 The point is noteworthy in Python versions prior to 3.7, where dictionaries are not guaranteed to be insertion ordered. With Python 3.7+, you can take advantage of insertion ordering and just use dict or a subclass of dict such as collections.defaultdict.






                    share|improve this answer

























                      1












                      1








                      1







                      You can use an ordered dictionary with default set values.1 Then iterate your list of dictionaries, using (number, favorite) as keys. This works since tuples are hashable and therefore permitted to be used as dictionary keys.



                      It's good practice to use a consistent structure. So, instead of having strings for single values and sets for multiple, use sets throughout:



                      from collections import OrderedDict, defaultdict

                      class DefaultOrderedDict(OrderedDict):
                      def __missing__(self, k):
                      self[k] = set()
                      return self[k]

                      d = DefaultOrderedDict() # Python 3.7+: d = defaultdict(set)

                      for i in lst:
                      d[(i['number'], i['favorite'])].add(i['color'])

                      res = ['number': num, 'favorite': fav, 'color': col for (num, fav), col in d.items()]

                      print(res)
                      # ['color': 'green', 'red', 'favorite': False, 'number': 1,
                      # 'color': 'red', 'favorite': True, 'number': 1,
                      # 'color': 'red', 'favorite': False, 'number': 2]


                      If you insist on having different types depending on number of colours, you can redefine the list comprehension to use a ternary statement:



                      res = ['number': num, 'favorite': fav, 'color': next(iter(col)) if len(col) == 1 else col 
                      for (num, fav), col in d.items()]

                      print(res)
                      # ['color': 'green', 'red', 'favorite': False, 'number': 1,
                      # 'color': 'red', 'favorite': True, 'number': 1,
                      # 'color': 'red', 'favorite': False, 'number': 2]



                      1 The point is noteworthy in Python versions prior to 3.7, where dictionaries are not guaranteed to be insertion ordered. With Python 3.7+, you can take advantage of insertion ordering and just use dict or a subclass of dict such as collections.defaultdict.






                      share|improve this answer













                      You can use an ordered dictionary with default set values.1 Then iterate your list of dictionaries, using (number, favorite) as keys. This works since tuples are hashable and therefore permitted to be used as dictionary keys.



                      It's good practice to use a consistent structure. So, instead of having strings for single values and sets for multiple, use sets throughout:



                      from collections import OrderedDict, defaultdict

                      class DefaultOrderedDict(OrderedDict):
                      def __missing__(self, k):
                      self[k] = set()
                      return self[k]

                      d = DefaultOrderedDict() # Python 3.7+: d = defaultdict(set)

                      for i in lst:
                      d[(i['number'], i['favorite'])].add(i['color'])

                      res = ['number': num, 'favorite': fav, 'color': col for (num, fav), col in d.items()]

                      print(res)
                      # ['color': 'green', 'red', 'favorite': False, 'number': 1,
                      # 'color': 'red', 'favorite': True, 'number': 1,
                      # 'color': 'red', 'favorite': False, 'number': 2]


                      If you insist on having different types depending on number of colours, you can redefine the list comprehension to use a ternary statement:



                      res = ['number': num, 'favorite': fav, 'color': next(iter(col)) if len(col) == 1 else col 
                      for (num, fav), col in d.items()]

                      print(res)
                      # ['color': 'green', 'red', 'favorite': False, 'number': 1,
                      # 'color': 'red', 'favorite': True, 'number': 1,
                      # 'color': 'red', 'favorite': False, 'number': 2]



                      1 The point is noteworthy in Python versions prior to 3.7, where dictionaries are not guaranteed to be insertion ordered. With Python 3.7+, you can take advantage of insertion ordering and just use dict or a subclass of dict such as collections.defaultdict.







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Jan 18 at 15:25









                      jppjpp

                      99.8k2161110




                      99.8k2161110





















                          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 Jan 18 at 7:09









                              Vineeth SaiVineeth Sai

                              2,48751323




                              2,48751323





















                                  0














                                  A friend of mine made the following function to solve this problem, without using any external libraries:



                                  def uniqifyColors(l):
                                  for elem in l:
                                  for item in l:
                                  if elem['number'] == item['number'] and elem['favorite'] == item['favorite']:
                                  for clr in item['color']:
                                  if clr not in elem['color']:
                                  elem['color'].append(clr)
                                  return l


                                  After using this Python function, he simply did a trivial uniqify to get the unique results from the list. It does not, however, keep a single color as a string, but rather a list with a single element.






                                  share|improve this answer



























                                    0














                                    A friend of mine made the following function to solve this problem, without using any external libraries:



                                    def uniqifyColors(l):
                                    for elem in l:
                                    for item in l:
                                    if elem['number'] == item['number'] and elem['favorite'] == item['favorite']:
                                    for clr in item['color']:
                                    if clr not in elem['color']:
                                    elem['color'].append(clr)
                                    return l


                                    After using this Python function, he simply did a trivial uniqify to get the unique results from the list. It does not, however, keep a single color as a string, but rather a list with a single element.






                                    share|improve this answer

























                                      0












                                      0








                                      0







                                      A friend of mine made the following function to solve this problem, without using any external libraries:



                                      def uniqifyColors(l):
                                      for elem in l:
                                      for item in l:
                                      if elem['number'] == item['number'] and elem['favorite'] == item['favorite']:
                                      for clr in item['color']:
                                      if clr not in elem['color']:
                                      elem['color'].append(clr)
                                      return l


                                      After using this Python function, he simply did a trivial uniqify to get the unique results from the list. It does not, however, keep a single color as a string, but rather a list with a single element.






                                      share|improve this answer













                                      A friend of mine made the following function to solve this problem, without using any external libraries:



                                      def uniqifyColors(l):
                                      for elem in l:
                                      for item in l:
                                      if elem['number'] == item['number'] and elem['favorite'] == item['favorite']:
                                      for clr in item['color']:
                                      if clr not in elem['color']:
                                      elem['color'].append(clr)
                                      return l


                                      After using this Python function, he simply did a trivial uniqify to get the unique results from the list. It does not, however, keep a single color as a string, but rather a list with a single element.







                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Jan 22 at 16:00









                                      KaanTheGuruKaanTheGuru

                                      859




                                      859



























                                          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%2fgroup-and-aggregate-a-list-of-dictionaries-by-multiple-keys%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

                                          How to check contact read email or not when send email to Individual?

                                          Displaying single band from multi-band raster using QGIS

                                          How many registers does an x86_64 CPU actually have?