single list to dictionary - python

I have this list:
single = ['key1', 'value1', 'key2', 'value2', 'key3', 'value3']
What's the best way to create a dictionary from this?
Thanks.

>>> single = ['key1', 'value1', 'key2', 'value2', 'key3', 'value3']
>>> dict(zip(single[::2], single[1::2]))
{'key3': 'value3', 'key2': 'value2', 'key1': 'value1'}

Similar to SilentGhost's solution, without building temporary lists:
>>> from itertools import izip
>>> single = ['key1', 'value1', 'key2', 'value2', 'key3', 'value3']
>>> si = iter(single)
>>> dict(izip(si, si))
{'key3': 'value3', 'key2': 'value2', 'key1': 'value1'}

This is the simplest I guess. You will see more wizardry in solution here using list comprehension etc
dictObj = {}
for x in range(0, len(single), 2):
dictObj[single[x]] = single[x+1]
Output:
>>> single = ['key1', 'value1', 'key2', 'value2', 'key3', 'value3']
>>> dictObj = {}
>>> for x in range(0, len(single), 2):
... dictObj[single[x]] = single[x+1]
...
>>>
>>> dictObj
{'key3': 'value3', 'key2': 'value2', 'key1': 'value1'}
>>>

L = ['key1', 'value1', 'key2', 'value2', 'key3', 'value3']
d = dict(L[n:n+2] for n in xrange(0, len(L), 2))

>>> single = ['key', 'value', 'key2', 'value2', 'key3', 'value3']
>>> dict(zip(*[iter(single)]*2))
{'key3': 'value3', 'key2': 'value2', 'key': 'value'}
Probably not the most readable version though ;)

You haven't specified any criteria for "best". If you want understandability, simplicity, easily modified to check for duplicates and odd number of inputs, works with any iterable (in case you can't find out the length in advance), NO EXTRA MEMORY USED, ... try this:
def load_dict(iterable):
d = {}
pair = False
for item in iterable:
if pair:
# insert duplicate check here
d[key] = item
else:
key = item
pair = not pair
if pair:
grumble_about_odd_length(key)
return d

Related

Creating nested dictionary from two lists one of which contains dictionaries

Very similar to this question but with an added caveat.
I have two lists identical in length. One contains my keys, and the other contains a list of dictionaries belonging to said keys. Example below (yes the Nones are intentional)
keys = ['key1', 'key2, 'key3']
vals = [[{'subkey1': 'val1', 'subkey2': 'val2'}], [{'subkey1: 'val2'},None],[{'subkey1':'val3'}, {'subkey3':'val1}, None, None]]
What I'd like to do is match each dictionary in each list to a key to create a nested dict.
So something like below:
final = {'key1':{'subkey1': 'val1', 'subkey2': 'val2'}, 'key2':{'subkey1': 'val2'}, 'key3':{'subkey1':'val3'}, {'subkey3':'val1'}}
I know we can use dictionary comprehension to do this. I created a dictionary of empty dicts.
s = {}
for i in keys:
for v in vals:
s[i] = {}
break
Then I wrote the following to iterate through the list of dicts I'd like to pair up accounting for the non dictionary values in my list.
x = 0
while x < len(keys):
for i in keys:
for element in vals[x]:
if isinstance(element, dict) == True:
s[str(i)].append(element)
else:
print('no')
x=x+1
However when I run this, I get AttributeError: 'NoneType' object has no attribute 'append'
How can I append to a dictionary using this for loop?
For the less readable dictionary comprehension solution
keys = ['key1', 'key2', 'key3']
vals = [
[{'subkey1': 'val1', 'subkey2': 'val2'}],
[{'subkey1': 'val2'}, None],
[{'subkey1': 'val3'}, {'subkey3':'val1'}, None, None]
]
s = {
k: {
sk: sv for d in (x for x in v if x is not None) for sk, sv in d.items()
} for k, v in zip(keys, vals)
}
Gives
{'key1': {'subkey1': 'val1', 'subkey2': 'val2'},
'key2': {'subkey1': 'val2'},
'key3': {'subkey1': 'val3', 'subkey3': 'val1'}}
This can be done fairly easily using a defaultdict:
from collections import defaultdict
keys = ['key1', 'key2', 'key3']
vals = [
[{'subkey1': 'val1', 'subkey2': 'val2'}],
[{'subkey1': 'val2'},None],
[{'subkey1':'val3'}, {'subkey3':'val1'}, None, None]
]
final = defaultdict(dict)
for idx, key in enumerate(keys):
for d in vals[idx]:
if d is not None:
final[key].update(d)
Output:
defaultdict(<class 'dict'>, {
'key1': {'subkey1': 'val1', 'subkey2': 'val2'},
'key2': {'subkey1': 'val2'},
'key3': {'subkey1': 'val3', 'subkey3': 'val1'}
})
can't use append on a dict
try this maybe?
keys = ['key1', 'key2', 'key3']
vals = [[{'subkey1': 'val1', 'subkey2': 'val2'}], [{'subkey1': 'val2'},None],[{'subkey1':'val3'}, {'subkey3':'val1'}, None, None]]
s = {}
for i in keys:
s[i] = {}
for i, key in enumerate(keys):
for element in vals[i]:
if isinstance(element, dict) == True:
s[str(key)].update(element)
print(s)
Output:
{'key1': {'subkey1': 'val1', 'subkey2': 'val2'}, 'key2': {'subkey1': 'val2'}, 'key3': {'subkey1': 'val3', 'subkey3': 'val1'}}

Split string of key=value into dictionary

I want to create a dictionary from a string that have key=value
s = "key1=value1 key2=value2 key3=value3"
print({r.split("=") for r in s})
Is it possible using dictionary comprehension? If yes, how?
You can first split on whitespace, then split on '='
>>> dict(tuple(i.split('=')) for i in s.split())
{'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
You could use map:
>>> s = "key1=value1 key2=value2 key3=value3"
>>> d = {k: v for k, v in map(lambda i: i.split('='), s.split())}
>>> {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}

Python convert a list to a specific dict

I have a list and I want to convert to a specific dict dict_a
Input:
a = ['AAA: key1', 'value1', 'value2', 'AAA: key2', 'value3', 'value4', 'value5', 'AAA: key3', 'value6', 'value7']
Output expected:
dict_a = {'key1': [value1, value2], 'key2': [value3, value4, value5], 'key3': [value6, value7]}
My attempt:
for elem in a:
if a.startswith(AAA:):
d_a = {elem}
This is one way using collections.defaultdict:
from collections import defaultdict
a = ['AAA: key1', ' value1', ' value2', 'AAA: key2', ' value3', ' value4', ' value5', 'AAA: key3', ' value6', ' value7']
d = defaultdict(list)
for x in a:
if not x.startswith('AAA'):
d[c].append(x.strip())
else:
c = x.split(': ')[1]
print(d)
# defaultdict(<class 'list'>, {'key1': ['value1', 'value2'], 'key2': ['value3', 'value4', 'value5'], 'key3': ['value6', 'value7']})
I like to use a generator for problems like this, accumulating a result unitl we see the next result start, then yielding the result we've collected.
def key_val_gen(a):
key = None
vals = []
for item in a:
if item.startswith('AAA: '):
if key:
yield key, vals
key = item.split(maxsplit=1)[1]
vals = []
else:
vals.append(item)
if key:
yield key, vals
a = ['AAA: key1', 'value1', 'value2', 'AAA: key2', 'value3', 'value4', 'value5', 'AAA: key3', 'value6', 'value7']
print(dict(key_val_gen(a)))
# {'key1': ['value1', 'value2'], 'key2': ['value3', 'value4', 'value5'], 'key3': ['value6', 'value7']}
from collections import defaultdict
result = defaultdict(list)
key = None
a = ['AAA: key1', ' value1', ' value2', 'AAA: key2', ' value3', ' value4', ' value5', 'AAA: key3', ' value6', ' value7']
for elem in a:
if elem.startswith('AAA:'):
key = elem.split(':')[1].strip()
elif key:
result[key].append(elem.strip())
print(result)
You could also use itertools.groupby to group items in "is a key" and "is a value" and then combine consecutive elements by using next on the same iterator:
>>> from itertools import groupby
>>> groups = (next(g).lstrip("AAA: ") if k else list(g)
... for k, g in groupby(a, key=lambda x: x.startswith("AAA: ")))
...
>>> {g: next(groups) for g in groups}
{'key1': ['value1', 'value2'],
'key2': ['value3', 'value4', 'value5'],
'key3': ['value6', 'value7']}

list of dictionaries from single dictionary

I have a dictionary like this
dict1 = {'key1': 'value1', 'key2': 'value2'}
how do I have an array of the keys and values as dictionaries like this
array_of_dict_values = [{'key1': 'value1'}, {'key2': 'value2'}]
What would be the easiest way to accomplish this?
You can do this:
>>> aDict = {'key1': 'value1', 'key2': 'value2'}
>>> aList = [{k:v} for k, v in aDict.items()]
>>> aList
[{'key2': 'value2'}, {'key1': 'value1'}]
While somebody already answered with how to do this, I'm going to answer with "you probably don't want to do this." If every entry is a dictionary with a single key, wouldn't a list of key-value pairs work just as well?
dictionary = {'key1': 'value1', 'key2': 'value2'}
print(list(dictionary.items()))
# [('key2', 'value2'), ('key1', 'value1')]

How to check if all specifiedn keys exist in array?

For example I have something like this:
{'key1': 'value', 'key2': 'value', 'key3': 'value','key4': 'value','key4': 'value'}
And have an array:
['key1', 'key3']
How to check if all keys from second array exists in first?
You can use all and a generator expression. This will iterate over your array and check that each key is in the keys of d. If at least one of the keys is missing then it'll return False.
d = {'key1': 'value', 'key2': 'value', 'key3': 'value','key4': 'value','key4': 'value'}
a = ['key1', 'key3']
all(key in d for key in a) # True
a2 = ['key1', 'key5']
all(key in d for key in a2) # False
You can use set.issubset() method to check
a = {'key1': 'value', 'key2': 'value', 'key3': 'value','key4': 'value','key4': 'value'}
b = ['key1', 'key3']
set(b).issubset(a)
#True
c = ['key1', 'key5']
set(c).issubset(a)
#False
Edit: apply issubset directly on a according to #Maroun Maroun comment
Another way (using set and issubset):
set(['key1', 'key3']).issubset(your_dict)
Use a loop and in operator with dict object:
adict = {'key1': 'value', 'key2': 'value', 'key3': 'value','key4': 'value','key4': 'value'}
keys_list = ['key1', 'key3']
for key in keys_list:
if key in adict:
print key
"in" can check if the key in a dict

Categories