Albert
Albert

Reputation: 2664

Building up a list of dictionaries from a few lists in Python

I have a few lists like this:

Pargs = [args.Pee, args.Pem,...,args.Pet] # 9 elements of boolean type
indices = [(0,0),(0,1),...,(2,2)] # 9 possible combinations (i,j), i = 0,1,2; j = 0,1,2
D = [{},{},...,{}] # 9 dictionaries, desired result

The result I want to see should look like this:

D = [{event:args.Pee,i:0,j:0},{event:args.Pem,i:0,j:1},...{event: args.Pet,i:2,j:2}]

The dictionaries must be ordered like shown above.

I tried

for d in D:
    for i in range(3):
        for j in range(3):
            d['i'],d['j'] = i,j

but it does not do the trick. I've tried numerous algorithms with zip(),product(),dict(), but to no avail...

Upvotes: 3

Views: 72

Answers (4)

martineau
martineau

Reputation: 123473

If Pargs and indices have the same number of elements, you can do it one of these two ways, depending on what you meant by "the dicts have to be ordered".

This will produce a list of dictionaries in the order shown in your question:

D = [{'event': parg, 'i':pair[0], 'j':pair[1]}
        for parg, pair in zip(Pargs, indices)]

If you meant you wanted the contents of each dictionary to be in the order shown (as well as their order in the list), you need to use a collections.OrderedDict to hold the data because regular dictionaries don't preserve the order of their contents (the key, value pairs).

from collections import OrderedDict

D = [OrderedDict([('event', parg), ('i', pair[0]), ('j', pair[1])])
        for parg, pair in zip(Pargs, indices)]

Upvotes: 0

timgeb
timgeb

Reputation: 78690

With a comprehension and OrderedDict, demo:

from collections import OrderedDict
pargs = ['arg1', 'arg2', 'arg3', 'arg4', 'arg5', 'arg6', 'arg7', 'arg8', 'arg9']
indices = ((x,y) for x in range(3) for y in range(3))
result = [OrderedDict([('event',p), ('i',i), ('j',j)]) for p,(i,j) in zip(pargs, indices)]
print(result) # [OrderedDict([('event', 'arg1'), ('i', 0), ('j', 0)]), OrderedDict([('event', 'arg2'), ('i', 0), ('j', 1)]), OrderedDict([('event', 'arg3'), ('i', 0), ('j', 2)]), OrderedDict([('event', 'arg4'), ('i', 1), ('j', 0)]), OrderedDict([('event', 'arg5'), ('i', 1), ('j', 1)]), OrderedDict([('event', 'arg6'), ('i', 1), ('j', 2)]), OrderedDict([('event', 'arg7'), ('i', 2), ('j', 0)]), OrderedDict([('event', 'arg8'), ('i', 2), ('j', 1)]), OrderedDict([('event', 'arg9'), ('i', 2), ('j', 2)])]

edit

If I misunderstood your requirements and the order within the dictionaries does not matter, you can do it without an OrderedDict like this:

result = [{'event':p, 'i':i, 'j':j} for p,(i,j) in zip(pargs, indices)]

Upvotes: 4

James
James

Reputation: 169

You want just a single loop where you keep track of multiple indices. Maybe this isn't what you're looking for, but go from here

i = 0
j = 0
for d in range(9):
    D[d] = {'event':Pargs[d], 'i':i, 'j':j}
    if j == 2:
        j = 0
        i += 1
    else:
        j += 1

Upvotes: 0

greg_data
greg_data

Reputation: 2293

From the looks of your question, you're looking to do something like the following:

>>> Pargs = [str(i) for i in range(9)]
>>> Pargs
9: ['0', '1', '2', '3', '4', '5', '6', '7', '8']
>>> indeces = [(i, j) for i in range(3) for j in range(3)]
10: [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
>>> D = [{'event':Pargs[ind], 'i':i[0], 'j':i[1]} for ind, i in enumerate(indeces)]
>>> D
11: [{'event': '0', 'i': 0, 'j': 0},
 {'event': '1', 'i': 0, 'j': 1},
 {'event': '2', 'i': 0, 'j': 2},
 {'event': '3', 'i': 1, 'j': 0},
 {'event': '4', 'i': 1, 'j': 1},
 {'event': '5', 'i': 1, 'j': 2},
 {'event': '6', 'i': 2, 'j': 0},
 {'event': '7', 'i': 2, 'j': 1},
 {'event': '8', 'i': 2, 'j': 2}]
>>> 

The key you seemed to be missing in your attempts was to iterate through indeces and Pargs at the same time.

Upvotes: 1

Related Questions