create a dictionary for a certain range in Python - python

I have a following dictionary:
d1 = {}
I need to assign it the following values, but only the first n values from the following list:
all_examples= ['A,1,1', 'B,2,1', 'C,4,4', 'D,4,5']
Final output: d1={"A":[1,1],"B":[2,1]}
1st version of the Question:
I have a following dictionary:
d1 = {'UID': 'A12B4', 'name': 'John', 'email': 'hi#example.com'}
How do I create a dictionary d2 such that d2 has the first n number of keys and values from d1?
2nd version of the Question
I have a following dictionary:
d1 = {}
I need to assign it the following values, but only the first n values from the following list:
all_examples= ['A,1,1', 'B,2,1', 'C,4,4', 'D,4,5']

How do I create a dictionary d2 such that d2 has the first n number of keys and values from d1?
I'm sorry to tell you, but you shouldn't do that. At least, not with the stock dict. The reason is that no order is guaranteed in a dict, and whenever you'll add or remove a value, the order of the dict CAN change.
But if you really insist you could do:
>>> d1 = {1:'a', 3:'b', 2:'c', 4:'d'}
>>> d1
{1: 'a', 2: 'c', 3: 'b', 4: 'd'}
>>> d.keys()[:2]
[1, 2]
>>> {k : d[k] for k in d.keys()[:2]}
{1: 'a', 2: 'c'}
but my suggestion to you is to use an OrderedDict object, that will guarantee the order of the elements within the dict:
>>> od = OrderedDict()
>>> od[1] = 'a'
>>> od[3] = 'b'
>>> od[2] = 'c'
>>> od[4] = 'd'
>>> od
OrderedDict([(1, 'a'), (3, 'b'), (2, 'c'), (4, 'd')])
>>> od.keys()[:2]
[1, 3]
>>> OrderedDict([(k, od[k]) for k in od.keys()[:2]])
OrderedDict([(1, 'a'), (3, 'b')])
Ok, looks like you just changed radically your question, so here's the new answer:
>>> all_examples= ['A,1,1', 'B,2,1', 'C,4,4', 'D,4,5']
>>> n = 2
>>> all_examples[:n]
['A,1,1', 'B,2,1']
here's how you select up to n values of a list.
once again, you're changing your question…
Final output: d1={"A":[1,1],"B":[2,1]}
well you can just do:
>>> {elt[0] : (elt[1], elt[2]) for elt in [elt.split(',') for elt in all_examples[:n]]}
{'A': ('1', '1'), 'B': ('2', '1')}
HTH

Related

Python convert list of tuples to dictionary with value of multiple tuples

I don't what to do with this because I can't append tuples and I just showed it with list as default
Dict = dict()
def convert(list_tup):
for a,b,c in list_tup:
letters = a,b
number = c
Dict.setdefault(number,[]).append(letters)
# I only want a multiple tuple values not list of tuple
return Dict
strings = [('w', 'x','2'), ('y', 'z', '3')]
print(convert(strings))
it prints {'2': [('w', 'x')], '3': [('y', 'z')]}
how can I add multiple tuples as value in one key?
I want my output to be like this:
{'2': ('w', 'x'), '3': ('y', 'z')}
The following dict comprehension should solve this
>>> {c: (a,b) for a,b,c in strings}
{'2': ('w', 'x'), '3': ('y', 'z')}
You can just make new entries in the output dictionary by keying c for the value (a,b):
def convert(list_tup):
d = {}
for a,b,c in list_tup:
d[c] = (a,b)
return d
But Cory's answer is more 🐍

Creating Python defaultdict using nested list of tuples

The scenario is that I have a 2-D list. Each item of the inner list is tuple (key, value pair). The key might repeat in the list. I want to create a default-dict on the fly, in such a way that finally, the dictionary stores the key, and the cumulative sum of all the values of that key from the 2-D list.
To put the code :
listOfItems = [[('a', 1), ('b', 3)], [('a', 6)], [('c', 0), ('d', 5), ('b', 2)]]
finalDict = defaultdict(int)
for eachItem in listOfItems:
for key, val in eachItem:
finalDict[key] += val
print(finalDict)
This is giving me what I want : defaultdict(<class 'int'>, {'a': 7, 'b': 5, 'c': 0, 'd': 5}) but I am looking for a more 'Pythonic' way using comprehensions. So I tried the below :
finalDict = defaultdict(int)
finalDict = {key : finalDict[key]+val for eachItem in listOfItems for key, val in eachItem}
print(finalDict)
But the output is : {'a': 6, 'b': 2, 'c': 0, 'd': 5} What is it that I am doing wrong? Or is it that when using comprehension the Dictionary is not created and modified on the fly?
Yes a comprehension can't be updated on-the-fly. Anyway, this task might be better suited to collections.Counter() with .update() calls:
>>> from collections import Counter
>>> c = Counter()
>>> for eachItem in listOfItems:
... c.update(dict(eachItem))
...
>>> c
Counter({'a': 7, 'b': 5, 'd': 5, 'c': 0})
This is because you do not assign any value to your finalDict inside your dict in comprehension.
In your dict in comprehension you are literally changing the type of finalDict
As far as I know you cannot assign value to your dict inside a dict in comprehension.
Here is a way to get the dictionnary you want
from functools import reduce
listOfItems = [[('a', 1), ('b', 3)], [('a', 6)], [('c', 0), ('d', 5), ('b', 2)]]
list_dict = [{key: val} for eachItem in listOfItems for key, val in eachItem]
def sum_dict(x, y):
return {k: x.get(k, 0) + y.get(k, 0) for k in set(x) | set(y)}
print(reduce(sum_dict, list_dict))
Simple solution without using additional modules:
inp_list = [[('a', 1), ('b', 3)], [('a', 6)], [('c', 0), ('d', 5), ('b', 2)]]
l = [item for sublist in inp_list for item in sublist] # flatten the list
sums = [(key, sum([b for (a,b) in l if a == key])) for key in dict(l)]
print(sums)
trying to use python's built-in methods instead of coding the functionality myself:
The long and explained solution
from itertools import chain, groupby
from operator import itemgetter
listOfItems = [[('a', 1), ('b', 3)], [('a', 6)], [('c', 0), ('d', 5), ('b', 2)]]
# just flat the list of lists into 1 list..
flatten_list = chain(*listOfItems)
# get all elements grouped by the key, e.g 'a', 'b' etc..
first = itemgetter(0)
groupedByKey = groupby(sorted(flatten_list, key=first), key=first))
#sum
summed_by_key = ((k, sum(item[1] for item in tups_to_sum)) for k, tups_to_sum in groupedByKey)
# create a dict
d = dict(summed_by_key)
print(d) # {'a': 7, 'b': 5, 'c': 0, 'd': 5}
~one line solution
from itertools import chain, groupby
from operator import itemgetter
first = itemgetter(0)
d = dict((k, sum(item[1] for item in tups_to_sum)) for k, tups_to_sum in groupby(sorted(chain(*listOfItems), key=first), key=first))
print(d) # {'a': 7, 'b': 5, 'c': 0, 'd': 5}

Python list of tuples to nested dict

I have a data structure as follows:
[(a,x1,1),(a,x2,5),(b,x1,1) ...]
and i want to turn it into a nested dictionary of the form
{a:{x1:1, x2:5}, b:{x1:1}...}
I tried
dictdata = {}
for row in rows:
ean = row[1].encode('ascii','ignore')
period = str(row[0])
value = row[2]
dictdata[ean]={} # init sub dictionary
dictdata[ean][period] = value
but every time I do dictdata[ean]={}, the contents get erased, so this will not work. If I do not initialise the sub-dictionary, I also cannot get it to work.
Any help appreciated
This is the kind of problem collections.defaultdict was built to solve:
https://docs.python.org/2/library/collections.html#collections.defaultdict
from collections import defaultdict
dictdata = defaultdict(dict)
rows = [('a','x1',1),('a','x2',5),('b','x1',1) ]
for row in rows:
ean = row[1].encode('ascii','ignore')
period = str(row[0])
value = row[2]
dictdata[period][ean] = value
dictdata
returns
{'a': {'x2': 5, 'x1': 1}, 'b': {'x1': 1}}
You can do it in one statement
rows = [('a','x1',1),('a','x2',5),('b','x1',1)]
result = dict()
for key1, key2, value in rows:
result.setdefault(key1, {}).update({key2: value})
Same thing but using defaultdict
from collections import defaultdict
rows = [("a", "x1", 1), ("a", "x2", 5), ("b", "x1", 1)]
d = defaultdict(dict)
for k, v, v2 in rows:
d[k][v] = v2
As a fix to your code, the proper way is to always if you have already the dictionary created, if not then instantiate one, like so:
>>> l
[('a', 'x1', 1), ('a', 'x2', 5), ('b', 'x1', 1)]
>>> d = {}
>>> for row in l:
ean = row[1].encode('ascii','ignore')
period = str(row[0])
value = row[2]
if period not in d:
d[period] = {}
if ean not in d[period]:
d[period][ean] = {}
d[period][ean] = value
>>> d
{'a': {b'x1': 1, b'x2': 5}, 'b': {b'x1': 1}}
You can also do it with defaultdict from collections, very straight forward:
>>> l = [('a','x1',1),('a','x2',5),('b','x1',1)]
>>>
>>> from collections import defaultdict
>>>
>>>
>>> d = defaultdict(dict)
>>>
>>> for k, k_sub, v in l:
d[k][k_sub] = v
>>> d
defaultdict(<class 'dict'>, {'a': {'x1': 1, 'x2': 5}, 'b': {'x1': 1}})
Solution for an arbitrary length of tuples:
l = [('a', 'x1', 1), ('a', 'x2', 5), ('b', 'x1', 1), ('a', 'x3', 'y1', 'z1', 7), ('a', 'x3', 'y1', 'z2', 666)]
def f(data):
def _f(store, keys, value):
if len(keys) == 1:
return {keys[0]: value}
store[keys[0]].update(_f(defaultdict(dict), keys[1:], value))
return store
result = defaultdict(dict)
for a in data:
_f(result, a[:-1], a[-1])
return dict(result)
print(f(l))
{'a': {'x1': 1, 'x2': 5, 'x3': {'y1': {'z2': 666}}}, 'b': {'x1': 1}}

How to cast a list to a dictionary

I have a list as a input made from tuples where the origin is the 1st object and the neighbour is the 2nd object of the tuple.
for example :
inp : lst = [('a','b'),('b','a'),('c',''),('a','c')]
out : {'a': ('a', ['b', 'c']), 'b': ('b', ['a']), 'c': ('c', [])}
first i tried to cast the list into a dictonary,
like this
dictonary = dict(lst)
but i got an error say that
dictionary update sequence element #0 has length 1; 2 is required
The simplest is probably inside a try / except block:
lst = [('a','b'),('b','a'),('c',''),('a','c')]
out = dict()
for k, v in lst:
try:
if v != '':
out[k][1].append(v)
else:
out[k][1].append([])
except KeyError:
if v != '':
out[k] = (k, [v])
else:
out[k] = (k, [])
print out
Which gives:
{'a': ('a', ['b', 'c']), 'b': ('b', ['a']), 'c': ('c', [])}
Here's how I did it, gets the result you want, you can blend the two operations into the same loop, make a function out of it etc, have fun! Written without Python one liners kung-fu for beginner friendliness!
>>> lst = [('a','b'),('b','a'),('c',''),('a','c')]
>>> out = {}
>>> for pair in lst:
... if pair[0] not in out:
... out[pair[0]] = (pair[0], [])
...
>>> out
{'a': ('a', []), 'c': ('c', []), 'b': ('b', [])}
>>> for pair in lst:
... out[pair[0]][1].append(pair[1])
...
>>> out
{'a': ('a', ['b', 'c']), 'c': ('c', ['']), 'b': ('b', ['a'])}
Just here to mention setdefault
lst = [('a','b'),('b','a'),('c',''),('a','c')]
d = {}
for first, second in lst:
tup = d.setdefault(first, (first, []))
if second and second not in tup[1]:
tup[1].append(second)

how to get key of dictionary in python

#some dictionary data{}
data = {1:[3,1,4,2,6]}
How to print the key of data i.e
print( key_of(data) ) #print in some ways.
output:
1
What I got till now is to use data.keys() function but whenever I use that function output will be like:
dict_keys([1])
So, what is the problem with that function. Can any one suggest me the answer.?
Simply do:
print(list(data))
to print all the keys. If you want to print a specific key then you'll have to search for it:
print(next(key for key, value in data.items() if value == something))
Note that there is no guarantee on the order of the keys.
>>> data = {'a': 1, 'aa': 2, 'b': 3, 'cd': 4}
>>> list(data)
['cd', 'a', 'b', 'aa']
>>> data['f'] = 1
>>> list(data)
['cd', 'a', 'b', 'aa', 'f']
>>> del data['a']
>>> list(data)
['cd', 'b', 'aa', 'f']
>>> data[1] = 1
>>> list(data)
['cd', 1, 'b', 'aa', 'f']
>>> for c in ('cde', 'fgh', 'ijk', 'rmn'):
... data[c] = 1
...
>>> list(data)
[1, 'aa', 'cde', 'cd', 'rmn', 'b', 'ijk', 'fgh', 'f']
Note how the keys do not follow alphabetical order, and how inserted keys aren't always appended to the list of keys. Also after some insertions some key were swapped. Removing/inserting keys can change the order in unpredictable ways.
There's no issue with dict.keys, it returns a view like object in Python3. You can use list() on the dict to get a list of keys.
>>> data = {1:[3,1,4,2,6]}
>>> keys = list(data)
>>> keys
[1]
>>> keys[0]
1
Note: If dict contains more than one keys then the order can be arbitrary and keys[0] can return any key.
>>> dic = {'a12': 1, 'sd':'sdfd', 'sdfsd': 'sdfsd'}
>>> list(dic) #Arbitrarily ordered
['sdfsd', 'sd', 'a12']

Categories

Resources