Home > front end >  Elegant way to concat all dict values together with a string carrier as a single string in Python
Elegant way to concat all dict values together with a string carrier as a single string in Python

Time:11-19

The objective is to concat all values in a dict into a single str.

Additionally, the \r\n also will be appended.

The code below demonstrates the end result.

However, I am looking for a more elegant alternative than the proposed code below.

d=dict(idx='1',sat='so',sox=[['x1: y3'],['x2: y1'],['x3: y3']],mul_sol='my love so')

s=''
for x in d:
    if x=='sox':
        for kk in d[x]:
            s=s  kk[0]  '\r\n'
    else:

        s=s  d[x] '\r\n'
print(s)

CodePudding user response:

following code have more control over what might have in the dictionary:

def conca(li):
  ret=''
  for ele in li:
    if isinstance(ele,str):
        ret  = ele   '\r\n'
    else:
        ret  = conca(ele) 
  return ret

print(conca([d[e] for e in list(d)]))

or if want a more versatile solution:

def conca(li):
 ret=''
 for ele in li:
    if isinstance(ele,str):
        ret  = ele   '\r\n'
    elif isinstance(ele, list):
        ret  = conca(ele)
    elif isinstance(ele, dict):
        ret  = conca(list(ele))
    else:
        raise Exception("value of diction can only be str, list or dict~")
 return ret

 print(conca([d[e] for e in list(d)]))

CodePudding user response:

Make a separate function that transforms the values, and then apply that using map.

d = {
    'idx': '1',
    'sat': 'so',
    'sox': [['x1: y3'],['x2: y1'],['x3: y3']],
    'mul_sol': 'my love so'
}

crlf = '\r\n'

import operator

def transform_sox(item):
    (key, val) = item
    if key == 'sox':
        return crlf.join(map(operator.itemgetter(0), val))
    else:
        return val

print(crlf.join(map(transform_sox, d.items())), crlf)

Not necessarily shorter, but clearer and more maintainable in my opinion.


Alternatively, if we can rely on the value type to determine the transformation, rather than the key:

def transform_sox(value):
    return value if isinstance(value, str) \
        else crlf.join(map(operator.itemgetter(0), value))

print(crlf.join(map(transform_sox, d.values())), crlf)

In the other direction, perhaps you need custom formatters for a few elements in the dictionary. In which case, look up the formatter for each element:

formatters = collections.defaultdict(lambda: lambda x: x)
formatters['sox'] = lambda x: crlf.join(map(operator.itemgetter(0), x))

def transform_sox(item):
    return formatters[item[0]](item[1])

print(crlf.join(map(transform_sox, d.items())), crlf)

CodePudding user response:

Use two generators, one for d['sox'] and another for everything else, and then use join() to concatenate strings.

s = ''.join(kk[0] for kk in d['sox'])   '\r\n'
s  = '\r\n'.join(val for key, val in d.items() if key != 'sox')
  • Related