Question

Out of curiosity is it possible to write the following logic as a nice dict comprehension?

a = "a c\nb c\nn q\n".split('\n')[:-1]

output = {}
for line in a:
    tmp = line.split(' ')
    output[tmp[0]] = tmp[1]

I wrote the following, but without a temporary assignment I have to split twice which is unfortunate:

{line.split(' ')[0]:line.split(' ')[1] for line in a}

Is something more elegant possible?

Was it helpful?

Solution

Use a nested list comprehension:

{p[0]:p[1] for p in [l.split(" ") for l in a]}

Output:

{'a': 'c', 'b': 'c', 'n': 'q'}

OTHER TIPS

In this case, I think the dict constructor is a little nicer since it will take an iterable of 2-sequences:

dict(line.split() for line in a)

Demo:

>>> a
['a c', 'b c', 'n q']
>>> dict(line.split() for line in a)
{'a': 'c', 'b': 'c', 'n': 'q'}

Highly specific to the whitespace in your particular input:

>>> a = "a c\nb c\nn q\n".split('\n')[:-1]
>>> {line[0]:line[2] for line in a}
{'a': 'c', 'b': 'c', 'n': 'q'}

does that work:

>>> a = "a c\nb c\nn q\n".split('\n')[:-1]

>>> {i[0]:i[1]  for line in a for i in [line.split(' ')]}
 {'a': 'c', 'b': 'c', 'n': 'q'}

In this case, you can use

dict(line.split(' ') for line in a)

but for more complicated "value processing" I usually find it easier to use either "normal" loop (like you did) or write small helper function:

def helper(val):
    ...
    return key, value

dict(helper(line) for line in a)

This is one thing (crippled lambda/anonymous function syntax) I really hate about python.

Use a nested list comprehension without a split.

>>> {line[0]:line[-1] for line in a}
{'a': 'c', 'b': 'c', 'n': 'q'}

Through python's re module,

>>> import re
>>> a = "a c\nb c\nn q\n"
>>> a
'a c\nb c\nn q\n'
>>> m = re.findall(r'^(.) (.)$', a, re.M)
>>> m
[('a', 'c'), ('b', 'c'), ('n', 'q')]
>>> dict(m)
{'a': 'c', 'b': 'c', 'n': 'q'}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top