Custom list of lists into dictionary - python

I have list of lists and I wish to create a dictionary with length of each element as values. I tried the following:
tmp = [['A', 'B', 'E'], ['B', 'E', 'F'], ['A', 'G']]
tab = []
for line in tmp:
tab.append(dict((k, len(tmp)) for k in line))
But it gives the output as:
[{'A': 3, 'B': 3, 'E': 3}, {'B': 3, 'E': 3, 'F': 3}, {'A': 3, 'G': 3}]
What is the modification that I should make to get the output:
{['A', 'B', 'E']:3, ['B', 'E', 'F']:3, ['A', 'G']:2}
Thanks in advance.
AP

You can't use list objects as dictionary keys, they are mutable and unhashable. You can convert them to tuple. Also note that you are looping over each sub list. You can use a generator expression by only looping over the main list:
In [3]: dict((tuple(sub), len(sub)) for sub in tmp)
Out[3]: {('A', 'B', 'E'): 3, ('A', 'G'): 2, ('B', 'E', 'F'): 3}

{tuple(t):len(t) for t in tmp}
Input :
[['A', 'B', 'E'], ['B', 'E', 'F'], ['A', 'G']]
Output :
{('A', 'G'): 2, ('A', 'B', 'E'): 3, ('B', 'E', 'F'): 3}
Dictionnary does not accept list as key, but tuple

Related

Extract all possible combinations of unique elements in dict of lists

I have this input:
d = {'a': ['A', 'B', 'C'], 'b': ['A', 'B', 'C'], 'c': ['D', 'E'], 'd': ['E', 'F', 'G']}
How can I extract all the possible unique samplings per list?
One of the possible output is for example:
d = {'a': 'A', 'b': 'B', 'c': 'D', 'd': 'E'}
or
d = {'a': 'B', 'b': 'A', 'c': 'E', 'd': 'F'}
and so on..
Any idea?
Thank you
This is what you are looking for
import itertools
keys, values = zip(*d.items())
permutations_dicts = [dict(zip(keys, v)) for v in itertools.product(*values)]

Finding the second level keys of a multi key dictionary Python?

I have a multi key dict in the following format. I am trying to access the list of the second level keys, however, it is returning the keys in the format of a dict_keys list. What I am trying to get is ['a', 'b', 'c', 'd', 'e', 'f']
dictTest={}
dictTest[1]={'a':1, 'b':2}
dictTest[2]={'c':1, 'd':2}
dictTest[3]={'e':1, 'f':2}
print(dictTest)
print(list([dictTest[i].keys() for i in dictTest.keys()]))
{1: {'a': 1, 'b': 2}, 2: {'c': 1, 'd': 2}, 3: {'e': 1, 'f': 2}}
[dict_keys(['a', 'b']), dict_keys(['c', 'd']), dict_keys(['e', 'f'])]
You could use itertools.chain in combination with mapping dict.keys to all the dicts values:
from itertools import chain
dictTest = {1: {'a': 1, 'b': 2}, 2: {'c': 1, 'd': 2}, 3: {'e': 1, 'f': 2}}
print(list(chain(*map(dict.keys, dictTest.values()))))
['a', 'b', 'c', 'd', 'e', 'f']
>>> [v2 for v1 in dictTest.values() for v2 in v1]
['a', 'b', 'c', 'd', 'e', 'f']
Try this:
# sum([list(b.keys()) for b in dictTest.values()], [])
# syntax improvement by #wwii
sum([list(b) for b in dictTest.values()], [])
Output:
['a', 'b', 'c', 'd', 'e', 'f']

Python: How to update dictionary with step-index from list

I am a week-old python learner. I would like to know: Let’s say:
list= [“a”, “A”, “b”, “B”, “c”, “C”]
I need to update them in dictionary to be a result like this:
dict={“a”:”A”, “b”:”B”, “c”:”C”}
I try to use index of list within dict.update({list[n::2]: list[n+1::2]} and for n in range(0,(len(list)/2))
I think i did something wrong. Please correct me.
Thank you in advance.
Try the following:
>>> lst = ['a', 'A', 'b', 'B', 'c', 'C']
>>> dct = dict(zip(lst[::2],lst[1::2]))
>>> dct
{'a': 'A', 'b': 'B', 'c': 'C'}
Explanation:
>>> lst[::2]
['a', 'b', 'c']
>>> lst[1::2]
['A', 'B', 'C']
>>> zip(lst[::2], lst[1::2])
# this actually gives a zip iterator which contains:
# [('a', 'A'), ('b', 'B'), ('c', 'C')]
>>> dict(zip(lst[::2], lst[1::2]))
# here each tuple is interpreted as key value pair, so finally you get:
{'a': 'A', 'b': 'B', 'c': 'C'}
NOTE: Don't name your variables same as python keywords.
Correct version of your program would be:
lst = ['a', 'A', 'b', 'B', 'c', 'C']
dct = {}
for n in range(0,int(len(lst)/2)):
dct.update({lst[n]: lst[n+1]})
print(dct)
Yours did not work because you used slices in each iteration, instead of accessing each individual element. lst[0::2] gives ['a', 'b', 'c'] and lst[1::2] gives ['A', 'B', 'C']. So for the first iteration, when n == 0 you are trying to update the dictionary with the pair ['a', 'b', 'c'] : ['A', 'B', 'C'] and you will get a type error as list can not be assigned as key to the dictionary as lists are unhashable.
You can use dictionary comprehension like this:
>>> l = list("aAbBcCdD")
>>> l
['a', 'A', 'b', 'B', 'c', 'C', 'd', 'D']
>>> { l[i] : l[i+1] for i in range(0,len(l),2)}
{'a': 'A', 'b': 'B', 'c': 'C', 'd': 'D'}
The below code would be the perfect apt to your question. Hope this helped you
a = ["a", "A", "B","b", "c","C","d", "D"]
b = {}
for each in range(len(a)):
if each % 2 == 0:
b[a[each]] = a[each + 1]
print(b)

Remove elements from nested list - Python

data = [['A', 'B', 'C', 'D'],
['E', 'F', 'G'],
['I', 'J'],
['A', 'B', 'C', 'E', 'F']]
I would like to remove unpopular elements (appearing only once) from the lists. So the results should look like this:
data = [['A', 'B', 'C'],
['E', 'F'],
['A', 'B', 'C', 'E', 'F']]
I was able to count the frequency of each element using the following codes:
from collections import Counter
Counter(x for sublist in data for x in sublist)
#output
Counter({'A': 2, 'C': 2, 'B': 2, 'E': 2, 'F': 2, 'D': 1, 'G': 1, 'I': 1, 'J': 1})
However, I am not sure how to use this count information to remove unpopular elements from the list. Any help?
Generate the new list based on the frequency information.
The following code uses nested list comprehension to do that:
from collections import Counter
freq = Counter(x for sublist in data for x in sublist)
data = [[x for x in row if freq[x] > 1] for row in data] # Remove non-popular item
data = [row for row in data if row] # Remove empty rows
# data => [['A', 'B', 'C'], ['E', 'F'], ['A', 'B', 'C', 'E', 'F']]
The complexity is similar. Just use map and filter function to make the code more pythonic.
from collections import Counter
data = [['A', 'B', 'C', 'D'],
['E', 'F', 'G'],
['I', 'J'],
['A', 'B', 'C', 'E', 'F']]
counter = Counter({'A': 2, 'C': 2, 'B': 2, 'E': 2, 'F': 2, 'D': 1, 'G': 1, 'I': 1, 'J': 1})
result = map(lambda row: filter(lambda x: counter.get(x) > 1, row), data)
print result

Removing weights from a dictionary

I have written a python program which gives me the following output:
{'D': {('B', 2.0), ('E', 1.0), ('C', 2.0)}, 'E': {('D', 1.0), ('B', 4.0), ('C', 3.0)},
'A': {('B', 1.0), ('C', 5.0)}, 'B': {('A', 1.0), ('D', 2.0), ('E', 4.0)}, 'C': {('E', 3.0),
('A', 5.0), ('D', 2.0)}`}`
These are nodes of a graph and their corresponding weights. I am trying to remove weights from the above output. Can anyone help me with this.? My output should look something like this :
{ "a" : ["b","c"],"b" : ["a", "e","d"],"c" : ["a", "d", "e"],
"d" : ["b","c","e"],"e" : ["b", "c","d"] }
{k:[x for x,_ in v] for k,v in d.items()} # use iteritems() in python 2
Out[32]:
{'A': ['C', 'B'],
'B': ['D', 'A', 'E'],
'C': ['D', 'A', 'E'],
'D': ['E', 'C', 'B'],
'E': ['C', 'B', 'D']}
dic = {'D': {('B', 2.0), ('E', 1.0), ('C', 2.0)},
'E': {('D', 1.0), ('B', 4.0), ('C', 3.0)},
'A': {('B', 1.0), ('C', 5.0)},
'B': {('A', 1.0), ('D', 2.0), ('E', 4.0)},
'C': {('E', 3.0), ('A', 5.0), ('D', 2.0)}}
dic_node = {}
for node in dic:
dic_node.update({node : [nnode for nnode, weigth in dic[node]]})
dic_node_one = {node : [nnode for nnode, weigth in dic[node]] for node in dic}
Out
>>> dic_node_one
{'A': ['C', 'B'],
'B': ['A', 'E', 'D'],
'C': ['A', 'D', 'E'],
'D': ['B', 'E', 'C'],
'E': ['B', 'C', 'D']}
>>> dic_node
{'A': ['C', 'B'],
'B': ['A', 'E', 'D'],
'C': ['A', 'D', 'E'],
'D': ['B', 'E', 'C'],
'E': ['B', 'C', 'D']}
Using dictionary comprehension, see Python Dictionary Comprehension:
from operator import itemgetter
dic = {'D': {('B', 2.0), ('E', 1.0), ('C', 2.0)},
'E': {('D', 1.0), ('B', 4.0), ('C', 3.0)},
'A': {('B', 1.0), ('C', 5.0)},
'B': {('A', 1.0), ('D', 2.0), ('E', 4.0)},
'C': {('E', 3.0), ('A', 5.0), ('D', 2.0)}}
# Simply extracting only the 1st element of the tuple from the key.
print {k:[alpha for alpha, num in v] for k,v in dic.items()}
print
# Extracting only the 1st element and sorting the tuples by its 2nd element, ascending.
print {k:[alpha for alpha, num in sorted(v, key=itemgetter(1))] for k,v in dic.items()}
print
# Extracting only the 1st element and sorting the tuples by its 2nd element, descending.
print {k:[alpha for alpha, num in sorted(v, key=itemgetter(1), reverse=True)] for k,v in dic.items()}
print
# Extracting only the 1st element and sorting by alphabetical order.
print {k:[alpha for alpha, num in sorted(v)] for k,v in dic.items()}
print
# Extracting only the 1st element and sorting by alphabetical order, lower()
print {k.lower():[alpha.lower() for alpha, num in sorted(v)] for k,v in dic.items()}
[out]:
{'A': ['C', 'B'], 'C': ['A', 'D', 'E'], 'B': ['A', 'E', 'D'], 'E': ['B', 'C', 'D'], 'D': ['B', 'E', 'C']}
{'A': ['B', 'C'], 'C': ['D', 'E', 'A'], 'B': ['A', 'D', 'E'], 'E': ['D', 'C', 'B'], 'D': ['E', 'B', 'C']}
{'A': ['C', 'B'], 'C': ['A', 'E', 'D'], 'B': ['E', 'D', 'A'], 'E': ['B', 'C', 'D'], 'D': ['B', 'C', 'E']}
{'A': ['B', 'C'], 'C': ['A', 'D', 'E'], 'B': ['A', 'D', 'E'], 'E': ['B', 'C', 'D'], 'D': ['B', 'C', 'E']}
{'a': ['b', 'c'], 'c': ['a', 'd', 'e'], 'b': ['a', 'd', 'e'], 'e': ['b', 'c', 'd'], 'd': ['b', 'c', 'e']}

Categories