3

I have a two-items list which I need to process. Those items are retrieved from a database, so the are actually header: value pairs but they are unparsed. They are strings separated by tabs, so the list looks like this:

my_list = ['header1\theader2\theader3\theader4', 'val1\tval2\tval3\tval4']

I need to create dict from the key - value pairs. Currently I do it with list comprehension:

keys = [k.strip() for k in my_list[0].split('\t')]
vals = [v.strip() for v in my_list[1].split('\t')]
return dict(zip(keys, vals))

I think there might be a way doing that using dict comprehension instead, but I couldn't get how. Is it possible to do parse the list items and return a dictionary with a one-liner or a more pythonic way?

Chen A.
  • 10,140
  • 3
  • 42
  • 61

2 Answers2

4

Try something like this

dict_comp = {k.strip():v.strip() for k,v in 
               zip(my_list[0].split('\t'), my_list[1].split('\t'))}
Pax Vobiscum
  • 2,551
  • 2
  • 21
  • 32
  • 1
    not my downvote, but the expression looks a bit cumbersome. I would have done `dict_comp = {k:v for k,v in zip(*(l.split('\t') for l in my_list))}` to avoid repeats, and you don't need strip. – Jean-François Fabre Feb 21 '18 at 16:31
  • 4
    why `strip()`? . – Chris_Rands Feb 21 '18 at 16:35
  • @Chris_Rands Simply trying to solve Vinny's problem more broadly. I cannot possibly imagine what he is doing with his code when we aren't looking :-) – Pax Vobiscum Feb 21 '18 at 16:39
  • 1
    @ChristianDean sure, but that's not the issue that we are trying to solve. If OP intends to use `strip`, by all means. I have to believe there was a reason to put it there to begin with. – Pax Vobiscum Feb 21 '18 at 16:42
  • Ah, I see! My bad @Pax. I didn't realize that the OP already had `str.strip` in his original code. In that case then yes, I do agree. One should strive to stay as true to the OP's code as possible. – Christian Dean Feb 21 '18 at 16:52
  • @Chris_Rands because sometimes the last item has new line or a tab characters – Chen A. Feb 21 '18 at 19:50
  • @Jean-FrançoisFabre your solution works on Python 2.7. I find it the most elegant solution. Thank you – Chen A. Feb 21 '18 at 19:51
4

I find the solution below the most elegant one:

dict_comp = dict(zip(*map(lambda x: x.split('\t'), my_list)))
print(dict_comp)  # -> {'header1': 'val1', 'header2': 'val2', 'header3': 'val3', 'header4': 'val4'}

Alternatively, the lambda can be substituted by a generator expression:

dict_comp = dict(zip(*(x.split('\t') for x in my_list)))

and if the strings do not contain any spaces, it can be shortened even further to:

dict_comp = dict(zip(*map(str.split, my_list)))  # kudos @Chris_Rands
Ma0
  • 15,057
  • 4
  • 35
  • 65