1

I have a GET query the format is like this:

?title1=a&test1=b&title2=a&test2=b&..&titleN=a&testN=b

The view contains just the code above

def index(request):
    # This is my view
    print request.GET.items():

This is the result returned I got from the view when I run the query :

{ 'title1':'a', 'test1':'b', 'title2':'a', 'test2':'b','titleN':'a', 'testN':'b' }

I want to create a new list of dictionary.

[
    {
        'title1' : 'a' , 
        'test1':'b'
    }, 
    {
        'title2' : 'a' ,
         'test2':'b'
    },
    {
        'titleN' : 'a',
        'testN':'b'
    }
]

As you can notice I want to arrange all the data by number and N here is a Number

The question is how to make a list like I mentioned above , the only convention is the dictionary contains keys with the same last number .

And then I want the list become like this :

[
    {
        'title' : 'a' , 
        'test':'b'
    }, 
    {
        'title' : 'a' ,
         'test':'b'
    },
    {
        'title' : 'a',
        'test':'b'
    }
]
Selim Ajimi
  • 344
  • 6
  • 21

5 Answers5

2

One way to solve the problem is to use regulare expressions for extracting the number and then itertools for grouping by that number.

import re, itertools

# This is the grouper function; used first for sorting, 
# then for actual grouping

def grouper(key):
    return re.findall(r'\d+$',key[0])[0]

# Sort the dictionary by the number
sorted_dict = sorted(original_dict.items(), key=grouper)

# Group the sorted dictionary items and convert the groups into dicts
result = [dict(vals) for _,vals in (itertools.groupby(sorted_dict, key=grouper))]
#[{'title1': 'a', 'test1': 'b'}, 
# {'title11': 'a', 'test11': 'b'}, 
# {'title2': 'a', 'test2': 'b'}]
DYZ
  • 55,249
  • 10
  • 64
  • 93
2

This one doesn't depend on the order of the items

import itertools
import re
num = re.compile('[0-9]+')
alpha = re.compile('[a-z]+')
query = { 'title1':'a', 'test1':'b', 'title2':'a', 'test2':'b','titleN':'a', 'testN':'b' }

result = [dict((num.sub('', w[0]), w[1]) for z, w in v) for i, v in itertools.groupby(((alpha.sub('', k), (k, v)) for k, v in query.items()), lambda x: x[0])]

# result:
# [{'test': 'b', 'title': 'a'},
#  {'test': 'b', 'title': 'a'},
#  {'testN': 'b', 'titleN': 'a'}]
solarc
  • 5,638
  • 2
  • 40
  • 51
1

Assuming the test and title will be holding integer suffix in continuous series of numbers starting from 1, below is a possible approach via using list comprehension to achieve this:

>>> my_dict = { 'title1':'a', 'test1':'b', 'title2':'a', 'test2':'b','title3':'a', 'test3':'b' }
>>> n = int(len(my_dict)/2)

>>> [{'title{}'.format(i), my_dict['title{}'.format(i)], 'test{}'.format(i), my_dict['test{}'.format(i)],} for i in range(1, n+1)]
[{'test1', 'b', 'a', 'title1'}, {'b', 'test2', 'a', 'title2'}, {'b', 'a', 'title3', 'test3'}]

I will suggest that instead of passing params to your apis as:

title1=a&test1=b&title2=a&test2=b

you should be passing it as:

title=a1,a2,a3&test=b1,b2,b3

The reason is: all the values should be mapped with single title and test parameter.

In this case, your code should be:

title = request.GET['title']
test = request.GET['test']

my_list = [{'title{}'.format(i): ti, 'test{}'.format(i): te } for i, (ti, te) in enumerate(zip(title, test))]

where value hold by my_list will be:

[{'test0': 'b1', 'title0': 'a1'}, {'test1': 'b2', 'title1': 'a2'}, {'title2': 'a3', 'test2': 'b3'}]
Moinuddin Quadri
  • 46,825
  • 13
  • 96
  • 126
1

Not so familiar with django, so there could be a more efficient way to do this, but... You could do something like the following:

 query_result = request.GET.items()
 list_of_dicts = []
 for i in range(1, N):
     d ={'title'+str(i):d['title'+str(i)],'test'+str(i):d['test'+str(i)]}
     list_of_dicts.append(d)
Al Avery
  • 72
  • 7
1

Cumbersome but still oneliner:

result = sorted([{k:v,"title"+k[4:]:d["title"+k[4:]]} for k,v in d.items() if k.startswith("test")],key=lambda x : sorted(x.keys()))
  • create the sub-dicts with testN & corresponding titleN keys+values (shortcut: 4 is the length of test string)
  • sort the list according to the sorted list of keys

result:

[{'test1': 'b', 'title1': 'a'}, {'test2': 'b', 'title2': 'a'}, {'titleN': 'a', 'testN': 'b'}]
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219