list with a tuple of dicts instead of list of dicts

Question:

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?

Asked By: Ron Kieftenbeld

||

Answers:

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]
Answered By: juanpa.arrivillaga