Search code examples
pythonnested-listswoocommerce-rest-api

list with a tuple of dicts instead of list of dicts


I have list of dicts

[{'id': 14786,
  'sku': '0663370-ZWA',
  'sizes': ['38', '40', '42', '44', '46'],
  'color': 'zwart'},
 {'id': 14787,
  'sku': '0663371-ZWA',
  'sizes': ['38', '40', '42', '44', '46'],
  'color': 'zwart'}]

want to place it in a datastructure for update attributes with woocommerce api

list_of_update_items = []

for index in lst_of_dcts:
    lst_of_attributes_items=[]
    attributes = {'id': 1, 'name': 'kleur', 'position': 0,'options': index['color'], 'variations': 'false','visible': 'true'},{'id': 6, 'options': index['sizes'], 'variations': 'true','visible': 'true'} 
    # make a list of attributes_items to use as value in the parent dict 
    lst_of_attributes_items.append(attributes)
    #make a dict with id as key and atribute_list as key
    update = {'id': index['id'], 'attributes': lst_of_attributes_items}
    list_of_update_items.append(update)
    #clear the list of attributes_items for the next iteration
    lst_of_attributes_items=[]
    #wrap in the top_dict
    data = {'update': list_of_update_items}

data results in

    {'update': [{'id': 14786,
   'attributes': [({'id': 1,
      'name': 'kleur',
      'position': 0,
      'options': 'zwart',
      'variations': 'false',
      'visible': 'true'},
     {'id': 6,
      'options': ['38', '40', '42', '44', '46'],
      'variations': 'true',
      'visible': 'true'})]},
  {'id': 14787,
   'attributes': [({'id': 1,
      'name': 'kleur',
      'position': 0,
      'options': 'zwart',
      'variations': 'false',
      'visible': 'true'},
     {'id': 6,
      'options': ['38', '40', '42', '44', '46'],
      'variations': 'true',
      'visible': 'true'})]}]}

makes a tuple of dicts in the list of 'attributes'_values. what I need is a list of dicts. What causes the tupple?


Solution

  • You use an intermediate:

    lst_of_attributes_items=[]
    

    Which you append a tuple of dicst to:

    attributes = {'id': 1, 'name': 'kleur', 'position': 0,'options': index['color'], 'variations': 'false','visible': 'true'},{'id': 6, 'options': index['sizes'], 'variations': 'true','visible': 'true'}
    list_of_update_items.append(update)
    

    Notice,

    attributes = {...}, {...}
    

    Creates a tuple.

    And then that list, with a single item (which is a tuple with two dicts) is set to the "attribute" key of your update dict:

    update = {'id': index['id'], 'attributes': lst_of_attributes_items}
    

    This doesn't make any sense, just make attributes a list instead of a tuple (since you dont want tuples... dont use tuples) then just put that directlyin the update dict. The whole thing can be simplified to:

    lst_of_dcts = [{'id': 14786,
      'sku': '0663370-ZWA',
      'sizes': ['38', '40', '42', '44', '46'],
      'color': 'zwart'},
     {'id': 14787,
      'sku': '0663371-ZWA',
      'sizes': ['38', '40', '42', '44', '46'],
      'color': 'zwart'}]
    
    
    list_of_update_items = []
    
    for index in lst_of_dcts:
        attributes = [
            {'id': 1, 'name': 'kleur', 'position': 0,'options': index['color'], 'variations': 'false','visible': 'true'},
            {'id': 6, 'options': index['sizes'], 'variations': 'true','visible': 'true'}
        ]
        list_of_update_items.append({'id': index['id'], 'attributes': attributes})
    
    
    data = {'update': list_of_update_items}
    

    Indeed, you could do the whole thing with a list comprehension (although, I probably wouldn't, since it isn't as readable to me):

    update_items = [
        {
            "id": index["id"],
            "attributes": [
                {
                    "id": 1,
                    "name": "kleur",
                    "position": 0,
                    "options": index["color"],
                    "variations": "false",
                    "visible": "true",
                },
                {
                    "id": 6,
                    "options": index["sizes"],
                    "variations": "true",
                    "visible": "true",
                },
            ],
        }
        for index in lst_of_dcts
    ]
    

    Although, using a helper function makes it pretty nice:

    def update_from_index(index):
        return {
            "id": index["id"],
            "attributes": [
                {
                    "id": 1,
                    "name": "kleur",
                    "position": 0,
                    "options": index["color"],
                    "variations": "false",
                    "visible": "true",
                },
                {
                    "id": 6,
                    "options": index["sizes"],
                    "variations": "true",
                    "visible": "true",
                },
            ],
        }
    
    
    update_items = [update_from_index(index) for index in lst_of_dcts]