Convert a dictionary into a list of tuples - python

Given a dictionary like this:
dic = {(7, 3): 18.51, (1, 3): 18.751, (5, 6): 34.917, (9, 8): 18.9738}
I want to convert it to a list of tuples like this:
my_list = [(7, 3, 18.51), (1, 3, 18.751), (5, 6, 34.917), (9, 8, 18.9738)]
I could have used a loop but I wonder if there is a neat way to do so instead of loops.

Simply use list(..) on some generator:
my_list = list(key+(val,) for key,val in dic.items())
This works since:
list(..) takes as input an iterable and converts it to a list; and
key+(val,) for key,val dic.items() is a generator that takes a pair of key-values of dic and transforms it into a tuple appending the val to the key.
Since we use a generator for a list, we can simplify this with list comprehension:
my_list = [key+(val,) for key,val in dic.items()]
Finally mind that the order in which the tuples occur is not fixed this is because the order how a dict stores elements is not fixed as well.

Related

multiply all elements in a list of tuples for elements in a list

I know it might sound easy but that problem is making me struggle.
I have a list of tuple as
[(0,1),(3,4)]
And I want to multiply all its values for all the values in a list like
[ 1, 2, 3]
So That in this case I will get a new list (nested) of tuples:
[[(0,1),(0,2),(0,3)],[(3,4),(6,8),(9,12)]]
How can I obtain this result?
Using a list comprehension :
tuples = [(0,1),(3,4)]
multipliers = [1, 2, 3]
results = [[(t[0]*m, t[1]*m) for m in multipliers] for t in tuples]
nested loops.
result = []
for t in tuples:
for m in multipliers:
result.append( (t[0]*m, t[1]*m) )
print(result)
gives:
[(0, 1), (0, 2), (0, 3), (3, 4), (6, 8), (9, 12)]
This is a list of tuples (the inner list).

Create dictionary from list elements in Python

I have a list similar to the following:
my_list =
[(1, 'item_19'),
(2, 'item_20'),
(3, 'item_21'),
(4, 'item_22'),
(5, 'item_23'),
(6, 'item_24'),
(7, 'item_25'),
(8, 'item_26'),
(9, 'item_27'),
(10, 'item_28'),
(11, 'item_29'),
(12, 'item_30'),
(13, 'item_31'),
(14, 'item_32'),
(15, 'item_33'),
(16, 'item_34'),
(17, 'item_35')]
I would like to make a dictionary of each element of the list, i.e. 1:'item_19',2:'item_20'
I currently do this:
list_1 = [l[0] for l in my_list]
list_2 = [l[1] for l in my_list]
and then zip the two lists
my_dict = dict(zip(list_1,list_2))
However there are more than a million element in my_list, so is this the best way to do this, or is there a quicker/more optimal way to do it(Memory wise).
To put this in context, I want a lookup table to check if elements in my_dict already exist in a different dictionary my_dict_old
The builtin dict function takes a list of tuples, which is exactly what you are providing:
>>> list_foo = [(1, 'item_1'), (2, 'item_2')]
>>> dict(list_foo)
{1: 'item_1', 2: 'item_2'}
If all you need to do is check for an item's existence, consider using set, as i in my_set is much faster than i in my_dict.values(), see the Python documentation on performance for more info. On my machine, for example, a lookup in a haystack of 10k entries is .443s with dict.values(), vs <.000s for set. If you need to associate values with the entries, then use a dictionary, otherwise use a set. For a more in-depth examination of lists vs. dictionaries (and also sets for the most part), refer to this answer.
dict accepts list of tuples, so you can just use your original list:
my_dict = dict(my_list)
And you are actually doing the same thing while calling zip
Also, if all keys are numbers and are not huge you can put all of them into array. Index would be the key. Though this solution depends on the actual task and might not be useful in some cases

How to sort a tuple based on a value within the list of tuples

In python, I wish to sort tuples based on the value of their last element. For example, i have a tuple like the one below.
tuples = [(2,3),(5,7),(4,3,1),(6,3,5),(6,2),(8,9)]
which after sort I wish to be in this format.
tuples = [(4,3,1),(6,2),(2,3),(6,3,5),(5,7),(8,9)]
How do i get to doing that?
Povide list.sort with an appropriate key function that returns the last element of a tuple:
tuples.sort(key=lambda x: x[-1])
You can use:
from operator import itemgetter
tuples = sorted(tuples, key=itemgetter(-1))
The point is that we use key as a function to map the elements on an orderable value we wish to sort on. With itemgetter(-1) we construct a function, that for a value x, will return x[-1], so the last element.
This produces:
>>> sorted(tuples, key=itemgetter(-1))
[(4, 3, 1), (6, 2), (2, 3), (6, 3, 5), (5, 7), (8, 9)]

How to sort dictionary on first element of the key (tuple)

I have a dictionary where each key is a tuple of values, I want to use the sorted() method to sort the dictionary on the very first element of my tuple. My code looks like this:
def mapData(header_list, dict_obj):
master_dict = {}
client_section_list = []
for element in header_list:
for row in dict_obj:
if (row['PEOPLE_ID'], row['DON_DATE']) == element:
client_section_list.append(row)
element = list(element)
element_list = [client_section_list[0]['DEDUCT_AMT'],
client_section_list[0]['ND_AMT'],
client_section_list[0]['DEDUCT_YTD'],
client_section_list[0]['NONDEDUCT_YTD']
]
try:
element_list.append((float(client_section_list[0]['DEDUCT_YTD']) +
float(client_section_list[0]['NONDEDUCT_YTD'])
))
except ValueError:
pass
element.extend(element_list)
element = tuple(element)
master_dict[element] = client_section_list
client_section_list = []
return sorted(master_dict, key=lambda key: key[master_dict[(1)]]
The last line is where I'm trying to find a way to sort it. My tuple looks like this:
(312178078,6/22/15,25,0,25,0,25.0)
Not entirely sure what you are trying to do, particularly what that function is supposed to return. I assume that you want to return the dictionary sorted by the first element in the key-tuples.
For this, there are two things to note:
Tuples are by default sorted by their first element (and if those are the same, then by the second, and so on), so no special key function is required
Regular dictionaries are unordered, i.e. they can not be permanently sorted in any order; you can only sort their items as a list, or use that list to create an OrderedDict instead
Some minimal example:
>>> d = {(2,4): 1, (1,3): 2, (1,2): 3, (3,1): 4}
>>> sorted(d)
[(1, 2), (1, 3), (2, 4), (3, 1)]
>>> sorted(d.items())
[((1, 2), 3), ((1, 3), 2), ((2, 4), 1), ((3, 1), 4)]
>>> collections.OrderedDict(sorted(d.items()))
OrderedDict([((1, 2), 3), ((1, 3), 2), ((2, 4), 1), ((3, 1), 4)])
In your case, you probably want this:
return collections.OrderedDict(sorted(master_dict.items()))
As #tobias_k has mentioned, sorted sorts tuples by its elements with decreasing priority, e.g. if you take a tuple (a, b, c) the highest sorting priority goes to a, then goes b etc (by default sorted uses object's comparison methods and this is how tuple comparison works). So sorted(master_dict) is all you need if you want a list of sorted keys, yet I believe you really want to leave the values
sorted(master_dict.items(), key=lambda key: key[0])
dict.items returns tuples of form (key, value) so here you need to specify the sorting key.

Converting nested lists to dictionary

Hi please I try to make a dictionary out of the nested lists below and I get a TypeError. Please help me fix it to get the desired output as shown below. Thanks
n1 = [[1,2],[3,4]]
n2 = [[(5,7),(10,22)],[(6,4),(8,11)]]
output = {1:(5,7), 2:(10,22), 3:(6,4), 4:(8,11)}
D1 = {}
for key, value in zip(n1,n2):
D1[key] = value
print D1
TypeError: unhashable type: 'list'
Your approach didn't work, because when you zip n1 and n2, the result will be like this
for key, value in zip(n1,n2):
print key, value
# [1, 2] [(5, 7), (10, 22)]
# [3, 4] [(6, 4), (8, 11)]
So, key is a list. But, it is not hashable. So it cannot be used as an actual key to a dictionary.
You can chain the nested lists to get them flattened and then you can zip them together with izip
from itertools import chain, izip
print dict(izip(chain.from_iterable(n1), chain.from_iterable(n2)))
# {1: (5, 7), 2: (10, 22), 3: (6, 4), 4: (8, 11)}
The beauty of this method is that, it will be very memory efficient, as it doesn't create any intermediate lists. So, this can be used even when the actual lists are very large.
Perhaps not the most pythonic way, but it's short:
In [8]: dict(zip(sum(n1, []), sum(n2, [])))
Out[8]: {1: (5, 7), 2: (10, 22), 3: (6, 4), 4: (8, 11)}
The sum() trick, is used for flattening the list.
Try this:
from itertools import chain
n1 = [[1,2],[3,4]]
n2 = [[(5,7),(10,22)],[(6,4),(8,11)]]
print dict(zip(chain(*n1), chain(*n2))

Categories