5

This is an extension of this question: How to split a string within a list to create key-value pairs in Python

The difference from the above question is the items in my list are not all key-value pairs; some items need to be assigned a value.

I have a list:

list = ['abc=ddd', 'ef', 'ghj', 'jkl=yui', 'rty']

I would like to create a dictionary:

dict = { 'abc':'ddd', 'ef':1, 'ghj':1, 'jkl':'yui', 'rty':1 }

I was thinking something along the lines of:

a = {}
for item in list:
   if '=' in item: 
     d = item.split('=')
     a.append(d) #I don't I can do this.
   else:
     a[item] = 1 #feel like I'm missing something here.
Community
  • 1
  • 1
Amelia N Chu
  • 323
  • 1
  • 5
  • 11

4 Answers4

13

For each split "pair", you can append [1] and extract the first 2 elements. This way, 1 will be used when there isn't a value:

print dict((s.split('=')+[1])[:2] for s in l)
Fabricator
  • 12,722
  • 2
  • 27
  • 40
  • 3
    This is a stunner. Brilliant! – Moses Koledoye Jun 08 '16 at 14:41
  • thanks @fabricator! Could explain why it doesn't work if you don't specifically extract the first two elements `[:2]`? Want to make sure I understand everything. – Amelia N Chu Jun 08 '16 at 14:45
  • 1
    @AmeliaNChu, just because `dict` method requires it. from the [documentation](https://docs.python.org/2/library/stdtypes.html#dict): `Otherwise, the positional argument must be an iterable object. Each item in the iterable must itself be an iterable with exactly two objects` – Fabricator Jun 08 '16 at 14:49
  • 1
    Note, will fail silently if there are ever two or more "=" in s. (It'll truncate at the second "="). – nigel222 Jun 08 '16 at 15:41
3

I would be using something similar to the post you linked.

d = dict(s.split('=') for s in a)

If you combine what you can learn from this post -- that is to use lists to create dictionaries -- and from using if/else in Python's list comprehension, you can come up with something like this:

d = dict(s.split("=", maxsplit=1) if "=" in s else [s, 1] for s in l)

What this does is add 1 to the end of the split list if there is no equal sign in it.

Community
  • 1
  • 1
Moon Cheesez
  • 2,489
  • 3
  • 24
  • 38
  • `[s]+[1]` can be shorten into `[s, 1]` – Hai Vu Jun 08 '16 at 14:38
  • This is the real stunner in my books - one line *and* completely readable. – nigel222 Jun 08 '16 at 15:25
  • Note, will crash (raise ValueError) if there are ever two or more "=" in `s`. Which may well be the best thing to do. – nigel222 Jun 08 '16 at 15:39
  • 1
    If you want to crash-proof it use `s.split("=", maxsplit=1)`. I had to look that up. But as soon as I thought of the need, I suspected that the split method must have provided for it, and it had. Which is why I love Python. – nigel222 Jun 08 '16 at 15:56
1
input_list = ['abc=ddd', 'ef', 'ghj', 'jkl=yui', 'rty']
output_dict = {}

for item in input_list:
    item_split = item.split('=')
    key = item_split[0]
    value = item_split[1] if len(item_split)>1 else 1
    output_dict[key] = value

a bit more concisely

for item in input_list:
    i_s = item.split('=')
    output_dict[i_s[0]] = i_s[1] if len(i_s)>1 else 1

This has the advantage that it doesn't append an extra element to each list created by splitting the elements of the input_list. Though, list comprehensions can be faster than a for loop

saq7
  • 1,528
  • 1
  • 12
  • 25
1

Here are the step-by-step approach.

In [50]: mylist = ['abc=ddd', 'ef', 'ghj', 'jkl=yui', 'rty']

In [51]: [element.split('=') for element in mylist]
Out[51]: [['abc', 'ddd'], ['ef'], ['ghj'], ['jkl', 'yui'], ['rty']]

In [52]: [element.split('=') + [1] for element in mylist]
Out[52]: [['abc', 'ddd', 1], ['ef', 1], ['ghj', 1], ['jkl', 'yui', 1], ['rty', 1]]

In [53]: [(element.split('=') + [1])[:2] for element in mylist]
Out[53]: [['abc', 'ddd'], ['ef', 1], ['ghj', 1], ['jkl', 'yui'], ['rty', 1]]

In [54]: dict((element.split('=') + [1])[:2] for element in mylist)
Out[54]: {'abc': 'ddd', 'ef': 1, 'ghj': 1, 'jkl': 'yui', 'rty': 1}
  • In order to convert your list in line 50 to a dictionary, you will need to convert it to the list in line 53.
  • Line 51. The first step is to split each element in the list by the equal sign. Each element now is transformed into a list of 1- or 2 elements. Notice that some element like 'ef' which does not have equal sign, we will have to fix that
  • Line 52. Next, we append 1 to each sub list. That should take care of the sublists with 1 element, but making some sublist 3 element long
  • Line 53: We normalize all sublist into 2-element ones by taking just the first two element and discard the third one if applicable. This list now is in the correct format to convert into a dictionary
  • Line 54. The last step is to take this list and convert it into a dictionary. Since the dict class can take a generator expression, we can safely remove the square brackets.

With that, here is the snippet:

mylist = ['abc=ddd', 'ef', 'ghj', 'jkl=yui', 'rty']
mydict = dict((element.split('=') + [1])[:2] for element in mylist)
Hai Vu
  • 37,849
  • 11
  • 66
  • 93