5

Consider the following dictionary comprehension:

foo = ['super capital=BLUE', 'super foo=RED']
patternMap = {x.split("=")[0]:x.split("=")[1] for x in foo}

It is fairly concise, but I don't like the fact that I need to call x.split('=') twice. I tried the following but it just results a syntax error.

patternMap = {y[0] : y[1] for y in x.split('=') for x in foo}

Is there a "proper" way to achieve the result in the first two lines without having to call x.split() twice or being more verbose?

Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
merlin2011
  • 71,677
  • 44
  • 195
  • 329
  • 1
    [Probably dupe](https://stackoverflow.com/questions/22980977/convert-list-of-strings-to-dictionary)? [Better target?](https://stackoverflow.com/questions/12739911/how-to-split-a-string-within-a-list-to-create-key-value-pairs-in-python) (although this one explicitly ask for shortest code) – user202729 Feb 27 '18 at 04:36
  • [Related but not on stackoverflow](https://www.quora.com/How-do-I-convert-list-of-key-value-values-to-dictionary-in-Python) – user202729 Feb 27 '18 at 04:38
  • [Or this?](https://stackoverflow.com/questions/1246444/convert-string-to-dict-using-list-comprehension-in-python) – user202729 Feb 27 '18 at 04:41
  • You can do something inelegant, like `{k:v for s in foo for k,v in (s.split('='),)}`, but you should just use a for-loop, generally – juanpa.arrivillaga Feb 27 '18 at 05:24

2 Answers2

7

Go straight to a dict with the tuples like:

Code:

patternMap = dict(x.split('=') for x in foo)

Test Code:

foo = ['super capital=BLUE', 'super foo=RED']
patternMap = {x.split("=")[0]: x.split("=")[1] for x in foo}
print(patternMap)

patternMap = dict(x.split('=') for x in foo)
print(patternMap)

# or if you really need a longer way
patternMap = {y[0]: y[1] for y in (x.split('=') for x in foo)}
print(patternMap)

Results:

{'super capital': 'BLUE', 'super foo': 'RED'}
{'super capital': 'BLUE', 'super foo': 'RED'}
{'super capital': 'BLUE', 'super foo': 'RED'}
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
1

I don't know if it's more verbose or not, but here's an alternative without calling split twice:

patternMap = {x1:x2 for x1, x2 in map(lambda f: f.split('='), foo)}
damores
  • 2,251
  • 2
  • 18
  • 31