0

I want to make a function with its input being a dictionary that can go from one kvpair to several. It should group the kvs in strings, with the format being:

str1 = '[{"name":key1, "v": value1}, {"name":key2,"v":value2},...{"name":key4,"v":4}]'

A string should only have 4 kv pairs at most. If there are more in the dictionary, then the function should build str2, str3 etc. For example, if there are 17 kv pairs, I need 5 strings (4*4 + 1), with the last string only printing key:value 17.

If the dictionary is always 4 items in length, I was doing it it like this

keys = list(dict.keys())
values = list(dict.values())

string= '['

for i in range(0, 4):
    string = string + ('{"name":"' + str(keys[i]) + '","v":' + str(values[i]) + '}')
    if i == 3:
        string = string + ']'
        break
    string = string + ','

But with dict now variable in length I don't see how to slice it properly so that strings are built using only 4 kv pairs

Joolz
  • 39
  • 5
  • Both? If dict always has 4 key:values, then the lists I make are also 4 items in length (and my code works). – Joolz Jul 22 '21 at 08:02

1 Answers1

2

Here you go

from itertools import zip_longest


def grouper(n, iterable, fillvalue=None):
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return zip_longest(fillvalue=fillvalue, *args)

def dict2str(in_dict, group_size=1):
    out_str = []
    for dict_group in grouper(group_size, in_dict.items()):
        out_str.append('[' + ', '.join([f'{{"name":{kv[0]}, "v":{kv[1]}}}' for kv in dict_group if kv != None]) + ']')
    return out_str


# Try out the function

my_dict = {'key1':1,
           'key2':2,
           'key3':3,
           'key4':4,
           'key5':5,
           'key6':6,
           'key7':7,
           'key8':8,
           'key9':9,
           'key10':10,
           'key11':11,
           'key12':12,
           'key13':13,
           'key14':14,
           'key15':15,
           'key16':16,
           'key17':17}

my_str = dict2str(my_dict, group_size=4)

What is happening here:

  • Iterate over groups of dictionary items using grouper
  • Use list comprehension to build up the right string for each key-value pair, in format {"name":key, "v":value}. Notice that grouper returns None if there are no more elements, so you have to make sure that your key-value pair is not None
  • Join all the elements in your group of items into a single string, using , as a separator and [ ] as starting and ending characters
  • Repeat it for each group of your dictionary and append results in a single list

Finally you get your list of strings, each clustering <=4 items (if group_size=4).

ALai
  • 739
  • 9
  • 18