Combining multiple lambda expressions into one line - python

implement in one line, using lambda expressions(map/filter/reduce),
function that gets list of different types and returns a dictionary which has these keys:
{‘c’: , ‘i’: , ‘f’: , ‘o’: }
'c' will present list of characters
'i' list of the integers
'f' list of the floats
'o' list of any other types
for exaple for the list:
myList = ['a', 2, 3, 's', 2.23]
the output will be:
{'c': ['a', 's'], 'i': [2, 3], 'f': [2.23], 'o': []}
So far is I made a method of it that works but I'll need somehow change it one line of code:
def q1a(myList):
myDict = dict.fromkeys(('c', 'i', 'f', 'o'))
myDict['c'] = list(filter(lambda x: type(x) is str, myList))
myDict['i'] = list(filter(lambda x: type(x) is int, myList))
myDict['f'] = list(filter(lambda x: type(x) is float, myList))
myDict['o'] = list(filter(lambda x: type(x) is not float and type(x) is not int and type(x) is not str, myList))
return myDict

You can use the below ugly one-liner
out = dict(zip(['c','i','f','o'], map(list, (filter(lambda x:isinstance(x,str), lst), filter(lambda x:isinstance(x,int), lst), filter(lambda x:isinstance(x,float), lst), filter(lambda x: not isinstance(x,(str,float,int)), lst)))))
You can also use functools.reduce with a helper function (not exactly one liner but doesn't need multiple filters so saves time):
def add(d, x):
d[x[0]].append(x[1])
return d
from functools import reduce
out = reduce(add,
map(lambda x: (('c',x) if isinstance(x,str)
else (('i',x) if isinstance(x,int)
else (('f',x) if isinstance(x,float)
else ('o',x)))), lst),
{'c':[],'i':[],'f':[],'o':[]})
Output:
{'c': ['a', 's'], 'i': [2, 3], 'f': [2.23], 'o': []}

This gets around the need to assign to the keys one at a time:
def q1a(myList):
return {
'c': list(filter(lambda x: type(x) is str, myList)),
'i': list(filter(lambda x: type(x) is int, myList)),
'f': list(filter(lambda x: type(x) is float, myList)),
'o': list(filter(lambda x: type(x) is not float and type(x) is not int and type(x) is not str, myList))
}

You could use list comprehensions and create a dictionary literal:
{
'c': [e for e in myList if type(e) is str],
'i': [e for e in myList if type(e) is int],
'f': [e for e in myList if type(e) is float],
'o': [e for e in myList if type(e) not in {float, int, str}]
}

The assignment seems to be asking you to take a functional approach to this and create a single operation.
One option would be a single reduce that manipulates a dict. This isn't as natural in python as in other languages because most dict operations return None. But you can still do it in a functional way if you try (it's a one-liner broken up for a (minor) improvement in readability):
from functools import reduce
l = ['a', 2, 3, 's', 2.23]
res = reduce(
lambda d, t: dict(d, **{t[1]: d[t[1]] + [t[0]]}),
map(lambda el: (el, {str: 'c', int: 'i', float: 'f'}.get(type(el), 'o')) , l),
dict.fromkeys('cifo', [])
)
print(res)
# {'c': ['a', 's'], 'i': [2, 3], 'f': [2.23], 'o': []}
This works by creating a list of tuples with the map():
list(map(lambda el: (el, {str: 'c', int: 'i', float: 'f'}.get(type(el), 'o')) , l),)
# [('a', 'c'), (2, 'i'), (3, 'i'), ('s', 'c'), (2.23, 'f')]
and then updating a dict inside the reduce that is initialized with empty lists created with dict.fromkeys('cifo', []).

If I'm writing this in Python, my first choice would be to skip the functional approach and use a boring for loop and a default dict.
from collections import defaultdict
def q1a(myList):
d = defaultdict(list)
for v in myList:
if isinstance(v, str):
type_code = 'c'
elif isinstance(v, int):
type_code = 'i'
elif isinstnace(v, float):
type_code = 'f'
else:
type_code = 'o'
d[tc].append(v)
return d
However, this suggests a solution using itertools.groupby. The big if statement makes for a simple function like
def type_code(v):
if isinstance(v, str):
type_code = 'c'
elif isinstance(v, int):
type_code = 'i'
elif isinstnace(v, float):
type_code = 'f'
else:
type_code = 'o'
return type_code
which could be written as a single conditional expression suitable for use in a lambda expression:
lambda v: ('c' if isinstance(v, str) else
'i' if isinstance(v, int) else
'f' if isinstance(v, float) else
'o')
In the following, I'll abbreviate the above lambda expression as tc for readability.
With itertools.groupby, you can partition a (sorted) list using a function that specifies which partition each element belongs to. The partitions so produced are suitable for use in a dict comprehension.
from itertools import groupby
def q1a(myList):
return {k: list(vs) for k, vs in groupby(sorted(myList, key=tc), tc)}
One slight glitch:
>>> q1a(['a', 2, 3, 's', 2.23])
{'c': ['a', 's'], 'f': [2.23], 'i': [2, 3]}
The result doesn't include a key that isn't produced by a value in the list. You'll have to merge the result with pre-initialized dict containing all the keys.
def q1a(myList):
return ({'c': [], 'i': [], 'f': [], 'o': []}
| {k: list(vs) for k, vs in groupby(sorted(myList, key=tc), tc)})
I don't use dict.fromKeys("cifo", []) because then each key defaults to a reference to the same empty list, rather than a distinct empty list for each.

You could use a double indirection to convert types into letters and setdefault to update the resulting dictionary:
def q1a(myList):
types = {str:'c', int:'i', float:'f'}
myDict = dict()
for x in myList:
myDict.setdefault(types.get(type(x),'o'),[]).append(x)
return myDict
myList = ['a', 2, 3, 's', 2.23]
print(q1a(myList))
{'c': ['a', 's'], 'i': [2, 3], 'f': [2.23]}
Using a defaultdict could simplify it a bit:
from collections import defaultdict
def q1a(myList):
types = defaultdict(lambda:'o',{str:'c', int:'i', float:'f'})
myDict = defaultdict(list)
for x in myList:
myDict[types[type(x)]].append(x)
return dict(myDict)

Related

Convert flattened list to list of dictionaries

I have the list containing strings and numbers. I am trying to convert into dictionary based on the type if it is string otherwise it would become a key.
Input:
lst = ['A', 1, 3, 4, 'B', 5, 'C', 2, 'D', 4]
Output:
[{'A': [1, 3, 4]}, {'B': [5]}, {'C': [2]}, {'D': 4}]
This is my working code so far, I it is definitely not as optimized as it could be:
main_array = []
small_array = []
se = {}
key = None
for i in range(len(lst)-1):
print(i)
if i == len(lst)-2:
if type(lst[i]) == str and type(lst[i+1]) == str:
main_array.append(lst[i])
main_array.append(lst[i+1])
elif type(lst[i]) == str and type(lst[i+1]) != str:
main_array.append({lst[i]: lst[i+1]})
elif type(lst[i]) != str and type(lst[i+1]) == str:
small_array.append(lst[i])
se.update({key: small_array})
main_array.append(se)
se = {}
small_array = []
main_array.append(lst[i+1])
elif lst[i] != type(str) and lst[i + 1] != type(str):
small_array.append(lst[i])
small_array.append(lst[i+1])
se.update({key: small_array})
main_array.append(se)
se = {}
small_array = []
else:
if type(lst[i]) == str and i != len(lst)-1:
if type(lst[i+1]) == str:
main_array.append(lst[i])
elif type(lst[i+1]) != str:
key = lst[i]
elif type(lst[i]) != str and i != len(lst)-1:
if type(lst[i+1]) == str:
small_array.append(lst[i])
se.update({key: small_array})
main_array.append(se)
se = {}
small_array = []
elif type(lst[i+1]) != str:
small_array.append(lst[i])
print(main_array)
Is there any way to optimize this code as I am intending to avoid nested loops?
It is much better to create an intermediate dictionary, then convert that dictionary to your desired result. Like this:
import collections
lst = ['A', 1, 3, 4, 'B', 5, 'C', 2, 'D', 4]
dct = collections.defaultdict(lambda: [])
key = None
for el in lst:
if type(el) == str:
key = el
continue
dct[key].append(el)
result = [{key: dct[key]} for key in dct]
print(result)
Try using a temporary list variable to build up the list until you encounter a str value in the list:
L = ['A', 1, 3, 4, 'B', 5, 'C', 2, 'D', 4]
res = {}
curr: list
for e in L:
if type(e) == str:
res[e] = curr = []
else:
curr.append(e)
print(res)
Print:
{'A': [1, 3, 4], 'B': [5], 'C': [2], 'D': [4]}
In case you really want a list of single-value dict elements:
L = ['A', 1, 3, 4, 'B', 5, 'C', 2, 'D', 4]
res = []
add = list.append
curr: list
for e in L:
if type(e) == str:
curr = []
add(res, {e: curr})
else:
add(curr, e)
print(res)
Output:
[{'A': [1, 3, 4]}, {'B': [5]}, {'C': [2]}, {'D': [4]}]
I was actually curious, so I timed it. It seems close to 40% faster than using an approach with defaultdict.
from timeit import timeit
from collections import defaultdict
from itertools import groupby
L = ['A', 1, 3, 4, 'B', 5, 'C', 2, 'D', 4]
# 1.385
print('dict: ', timeit("""
res = []
add = list.append
curr: list
for e in L:
if type(e) == str:
curr = []
add(res, {e: curr})
else:
add(curr, e)
""", globals=globals()))
# 1.619
print('no temp list: ', timeit("""
res = []
key = None
add = list.append
for el in L:
if type(el) == str:
key = el
add(res, {el: []})
continue
add(res[-1][key], el)
""", globals=globals()))
# 2.150
print('defaultdict: ', timeit("""
dct = defaultdict(list)
key = None
for el in L:
if type(el) == str:
key = el
else:
dct[key].append(el)
result = [{key: dct[key]} for key in dct]
""", globals=globals()))
# 2.578
print('groupby: ', timeit("""
groups = groupby(L, type)
result = []
try:
while groups:
result.append({ list(next(groups)[1])[0] : list(next(groups)[1]) })
except StopIteration:
pass
""", globals=globals()))
One way to do this is to simply add a new dictionary every time a string comes up, then append to that list until the next string. Like this:
lst = ['A', 1, 3, 4, 'B', 5, 'C', 2, 'D', 4]
res = []
key = None
for el in lst:
if type(el) == str:
key = el
res.append({el: []})
continue
res[-1][key].append(el)
print(res)
I believe that this would be much faster than my other answer. All you need is one result array and one variable to keep track of the key.
When I tested it, this method is slightly slower than rv.kvetch's answer, however there is no need to store a temporary list. This method is cleaner (no need to add the last list) and uses less memory in theory.
Just for fun, you could use itertools.groupby to group your list by the type of value, then iterate the result to get the key and value pairs for each dict to be pushed to the result list:
import itertools
lst = ['A', 1, 3, 4, 'B', 5, 'C', 2, 'D', 4]
groups = itertools.groupby(lst, type)
result = []
try:
while groups:
result.append({ list(next(groups)[1])[0] : list(next(groups)[1]) })
except StopIteration:
pass
Output:
[
{'A': [1, 3, 4]},
{'B': [5]},
{'C': [2]},
{'D': [4]}
]

how can i get a dictionary to produce two dictionaries with some keys the same

I have a dictionary, what:
what = {'a': ['b'], 'c': ['d\n', 'e\n', 'f'], 'd': ['f', 'g']}
and need to get the items with '/n' separate and without '/n' (order is important, need to sort the values.):
[[{'a': ['b'], 'c': ['f'], 'd': ['f', 'g']}], [{'c': ['d\n', 'e\n']}]]
This is what I tried:
def lst(profiles_file: TextIO):
solve_lst = []
new_lst = fix_files(profiles_file)
for k, v in new_lst.items():
for i in v:
if i.find('\n') != -1:
get_index = [v.index(i)]
solve_lst.append(get_index)
return solve_lst
How can i get this without doing anything to complicated?
Here's a solution using defaultdict
from collections import defaultdict
def lst(profiles_file: TextIO):
initial_dict = fix_files(profiles_file)
with_n = defaultdict(list)
without_n = defaultdict(list)
for k, v in initial_dict.items():
for item in v:
if '\n' in item:
with_n[k].append(item)
else:
without_n[k].append(item)
return [without_n, with_n]

Flatten Arbitrary Length of Dictionary Items Into List of Paths in Python

So, I have read quite a few posts on flattening dictionaries recursively in Python. None (save one) have come close to what I'm looking for. First, a quick example of what I am trying to accomplish:
Example dictionary with mixed entries: (keys and values will always be of mixed types)
{'a': [{'b': {'c': 'd', 'e': 'f', 'g': 'h',
'i': {'j': {'k': ['l'], 'm': 'n'}},
'o': {'p': {'q': ['r', 's' ], 't': 'u'}}
}
}]
}
Desired output:
{'a/b/c/d',
'a/b/e/f',
'a/b/g/h',
'a/b/i/j/k/l',
'a/b/i/j/m/n',
'a/b/o/p/q/r',
'a/b/o/p/q/s',
'a/b/o/p/t/u'}
The function should (theoretically) work on lists as well.
To explain a bit about what I am doing, I am attempting to search through a Mac plist and other attempts to search by key or value have been shaky at best. To compensate, I want to try a different approach. Convert the dictionary to a list of 'paths' and then just search the paths.
I tried myself (and partially succeeded) and then I found a better solution in the form of this:
def flatten(structure, key="", path="", flattened=None):
if flattened is None:
flattened = {}
if type(structure) not in(dict, list):
flattened[((path + "/") if path else "") + key] = structure
elif isinstance(structure, list):
for i, item in enumerate(structure):
flatten(item, "", "/".join(filter(None,[path,key])), flattened)
else:
for new_key, value in structure.items():
flatten(value, new_key, "/".join(filter(None,[path,key])), flattened)
return flattened
This works well but there are a few undesired effects. First, the output is as follows:
{'a/b/c' : 'd',
'a/b/e' : 'f',
'a/b/g' : 'h',
'a/b/i/j/k/': 'l',
'a/b/i/j/m' : 'n',
'a/b/o/p/q/': 's',
'a/b/o/p/t' : 'u'}
This is returning a dictionary of key/value pairs. I'd rather have a list of string paths. Secondly, and more importantly, you'll notice, the script has stripped values where the value was a list. Only appending the last item of the list.
'a/b/o/p/q/': 's' # there should be another entry with 'r' as the value.
I have spent a fair amount of time fiddling with the output and trying to completely wrap my head around the problem to no avail. It may just be my lac of understanding Python, but the output I want should be possible.
I try not to ask questions unless I have run out of options and here I am. Please do not mark as a duplicate, as other questions aren't quite looking to accomplish what I am looking for.
Thank you for your time and assistance/guidance.
Python 2.7:
def flatten(structure):
if isinstance(structure, basestring):
return [structure]
ret = []
if isinstance(structure, list):
for v in structure:
ret.extend(flatten(v))
elif isinstance(structure, dict):
for k, v in structure.items():
ret.extend(k + '/' + f for f in flatten(v))
return ret
print sorted(flatten(structure))
Output:
['a/b/c/d', 'a/b/e/f', 'a/b/g/h', 'a/b/i/j/k/l', 'a/b/i/j/m/n', 'a/b/o/p/q/r', 'a/b/o/p/q/s', 'a/b/o/p/t/u']
Or, if you don't care about the order, you can simply print flatten(structure).
Here's how I would do it in Python 3.3+:
def flatten(exp):
def sub(exp, res):
if type(exp) == dict:
for k, v in exp.items():
yield from sub(v, res+[k])
elif type(exp) == list:
for v in exp:
yield from sub(v, res)
else:
yield "/".join(res+[exp])
yield from sub(exp, [])
testing:
l={'a': [{'b': {'c': 'd', 'e': 'f', 'g': 'h',
'i': {'j': {'k': ['l'], 'm': 'n'}},
'o': {'p': {'q': ['r', 's' ], 't': 'u'}}
}
}]
}
for i in sorted(flatten(l)):
print(i)
yields
a/b/c/d
a/b/e/f
a/b/g/h
a/b/i/j/k/l
a/b/i/j/m/n
a/b/o/p/q/r
a/b/o/p/q/s
a/b/o/p/t/u
EDIT translation to Python 2 is trivial:
def flatten(exp):
def sub(exp, res):
if type(exp) == dict:
for k, v in exp.items():
for r in sub(v, res+[k]):
yield r
elif type(exp) == list:
for v in exp:
for r in sub(v, res):
yield r
else:
yield "/".join(res+[exp])
for r in sub(exp, []):
yield r
then
>>> for i in sorted(flatten(l)):
... print i
...
a/b/c/d
a/b/e/f
a/b/g/h
a/b/i/j/k/l
a/b/i/j/m/n
a/b/o/p/q/r
a/b/o/p/q/s
a/b/o/p/t/u

Python dictionaries adding different values to a key?

I want to make a function that goes through a list and makes a dictionary with keys for each thing in the list and values of the one thing in the list following the key.
def function(s : str) -> {str:{str}}:
listt=list(s)
dictt= {}
for i in listt[:-1]:
if i not in dictt:
dictt[i] = set()
dictt[i].update(listt[listt.index(i)+1])
return dictt
print(function('bookeeper'))
should return:
{'b': {'o'}, 'k': {'e'}, 'p': {'e'}, 'o': {'o', 'k'}, 'e': {'e', 'p', 'r'}}
but actually returns:
{'b': {'o'}, 'k': {'e'}, 'p': {'e'}, 'o': {'o'}, 'e': {'e'}}
Don't use list.index(); that'll only match the first occurrence of a letter; for 'o' it'll never find the second 'o'; you'll only repeatedly add the same characters to the sets.
Use enumerate() to add an index to your loop, instead:
def function(s : str) -> {str:{str}}:
listt=list(s)
dictt= {}
for next_index, char in enumerate(listt[:-1], 1):
if char not in dictt:
dictt[char] = set()
dictt[char].update(listt[next_index])
return dictt
I started enumerate() at 1 instead of the default 0 so it always represents the next position.
Demo:
>>> def function(s : str) -> {str:{str}}:
... listt=list(s)
... dictt= {}
... for next_index, char in enumerate(listt[:-1], 1):
... if char not in dictt:
... dictt[char] = set()
... dictt[char].update(listt[next_index])
... return dictt
...
>>> print(function('bookeeper'))
{'p': {'e'}, 'o': {'o', 'k'}, 'e': {'p', 'r', 'e'}, 'b': {'o'}, 'k': {'e'}}
Now that it is working, lets simplify this a little; use dict.setdefault() to add the set to the dictionary when the key is missing, for example. Strings are already sequences, no need to cast them to a list either:
def function(s : str) -> {str:{str}}:
dictt = {}
for next_index, char in enumerate(s[:-1], 1):
dictt.setdefault(char, set()).update(s[next_index])
return dictt
Instead of enumerate(), we could also use zip() to pair up the letters of the word:
def function(s : str) -> {str:{str}}:
dictt = {}
for char, next_char in zip(s, s[1:]):
dictt.setdefault(char, set()).update(next_char)
return dictt
Your problem is that index() always returns the first index in the string, so you'll be adding the same character to the set over and over.
Try something like
def function(s : str) -> {str:{str}}:
dictt = {}
for pos, char in enumerate(s[:-1]):
if char not in dictt:
dictt[char] = set()
dictt[char].update(s[pos+1])
return dictt
Here is the another answer:
def func(string):
arr = set(string)
res = {}
for char in arr:
index = [i for i in range(len(string)) if string[i] == char]
temp = []
for i in index:
if i == len(string) - 1:
continue
temp.append(string[i + 1])
if temp:
res[char] = temp
return res
func('bookeeper')
>>> {'b': ['o'], 'e': ['e', 'p', 'r'], 'k': ['e'], 'o': ['o', 'k'], 'p': ['e']}

Converting dictionaries to list sorted by values, with multiple values per item

In Python, I have a simple problem of converting lists and dictionaries that I have solved using explicit type check to tell the difference between integers and list of integers. I'm somewhat new to python, and I'd curious if there is a more 'pythonic' way to solve the problem,i.e. that avoids an explicit type check.
In short: Trying to sort a dictionary's keys using the values, but where each key can have multiple values, and the key needs to appear multiple times in the list. Data comes in the form {'a':1, 'b':[0,2],...}. Everything I have come up (using sorted( , key = ) ) with is tripped up by the fact the values that occur once can be specified not as an integer instead of a length of list 1.
I'd like to convert between dictionaries of the form {'a':3, 'b':0, 'c':[2,4], 'd':[1,5]} and lists ['b', 'd', 'c', 'a', 'c', 'd'] (the positions of the items in list being specified by the values in the dictionary).
The function list_to_dictionary should have a key for each item appearing in the list with the value giving the location in the list. In case an item appears more than once, the value should be a list storing all of those locations.
The function dictionary_to_list should create a list consisting of the keys of the dictionary, sorted by value. In case the value is not a single integer but instead a list of integers, that key should appear in the list multiple times at the corresponding sorted locations.
My solution was as follows:
def dictionary_to_list(d):
"""inputs a dictionary a:i or a:[i,j], outputs a list of a sorted by i"""
#Converts i to [i] as value of dictionary
for a in d:
if type(d[a])!=type([0,1]):
d[a] = [d[a]]
#Reverses the dictionary from {a:[i,j]...} to {i:a, j:a,...}
reversed_d ={i:a for a in d for i in d[a]}
return [x[1] for x in sorted(reversed_d.items(), key=lambda x:x[0])]
def list_to_dictionary(x):
d = {}
for i in range(len(x)):
a = x[i]
if a in d:
d[a].append(i)
else:
d[a]=[i]
#Creates {a:[i], b:[j,k],...}
for a in d:
if len(d[a])==1:
d[a] = d[a][0]
#Converts to {a:i, b:[j,k],...}
return d
I can't change the problem to have lists of length 1 in place of the single integers as the values of the dictionaries due to the interaction with the rest of my code. It seems like there should be a simple way to handle this but I can't figure it out. A better solution here would have several applications for my python scripts.
Thanks
def dictionary_to_list(data):
result = {}
for key, value in data.items():
if isinstance(value, list):
for index in value:
result[index] = key
else:
result[value] = key
return [result[key] for key in sorted(result)]
def list_to_dictionary(data):
result = {}
for index, char in enumerate(data):
result.setdefault(char, [])
result[char].append(index)
return dict((key, value[0]) if len(value) == 1 else (key, value) for key, value in result.items())
dictData = {'a':3, 'b':0, 'c':[2,4], 'd':[1,5]}
listData = ['b', 'd', 'c', 'a', 'c', 'd']
print dictionary_to_list(dictData)
print list_to_dictionary(listData)
Output
['b', 'd', 'c', 'a', 'c', 'd']
{'a': 3, 'c': [2, 4], 'b': 0, 'd': [1, 5]}
In [17]: d = {'a':3, 'b':0, 'c':[2,4], 'd':[1,5]}
In [18]: sorted(list(itertools.chain.from_iterable([[k]*(1 if isinstance(d[k], int) else len(d[k])) for k in d])), key=lambda i:d[i] if isinstance(d[i], int) else d[i].pop(0))
Out[18]: ['b', 'd', 'c', 'a', 'c', 'd']
The call is to:
sorted(
list(
itertools.chain.from_iterable(
[[k]*(1 if isinstance(d[k], int) else len(d[k]))
for k in d
]
)
),
key=lambda i:d[i] if isinstance(d[i], int) else d[i].pop(0)
)
The idea is that the first part (i.e. list(itertools.chain.from_iterable([[k]*(1 if isinstance(d[k], int) else len(d[k])) for k in d])) creates a list of the keys in d, repeating by the number of values associated with it. So if a key has as single int (or a list containing only one int) as its value, it appears once in this list; else, it appears as many times as there are items in the list.
Next, we assume that the values are sorted (trivial to do as a pre-processing step, otherwise). So now, what we do is to sort the keys by their first value. If they have only a single int as their value, it is considered; else, the first element in the list containing all its values. This first element is also removed from the list (by the call to pop) so that subsequent occurrences of the same key won't reuse the same value
If you'd like to do this without the explicit typecheck, then you could listify all values as a preprocessing step:
In [22]: d = {'a':3, 'b':0, 'c':[2,4], 'd':[1,5]}
In [23]: d = {k:v if isinstance(v, list) else [v] for k,v in d.iteritems()}
In [24]: d
Out[24]: {'a': [3], 'b': [0], 'c': [2, 4], 'd': [1, 5]}
In [25]: sorted(list(itertools.chain.from_iterable([[k]*len(d[k]) for k in d])), key=lambda i:d[i].pop(0))
Out[25]: ['b', 'd', 'c', 'a', 'c', 'd']
def dictionary_to_list(d):
return [k[0] for k in sorted(list(((key,n) for key, value in d.items() if isinstance(value, list) for n in value))+\
[(key, value) for key, value in d.items() if not isinstance(value, list)], key=lambda k:k[1])]
def list_to_dictionary(l):
d = {}
for i, c in enumerate(l):
if c in d:
if isinstance(d[c], list):
d[c].append(i)
else:
d[c] = [d[c], i]
else:
d[c] = i
return d
l = dictionary_to_list({'a':3, 'b':0, 'c':[2,4], 'd':[1,5]})
print(l)
print(list_to_dictionary(l))

Categories