Converting nested lists to dictionary - python

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))

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).

Sorting in a dictionary [duplicate]

This question already has answers here:
How do I sort a dictionary by value?
(34 answers)
Closed 2 years ago.
Im trying to get the output from my dictionary to be ordered from their values in stead of keys
Question:
ValueCount that accepts a list as a parameter. Your function will return a list of tuples. Each tuple will contain a value and the number of times that value appears in the list
Desired outcome
>>> data = [1,2,3,1,2,3,5,5,4]
>>> ValueCount(data)
[(1, 2), (2, 2), (5, 1), (4, 1)]
My code and outcome
def CountValues(data):
dict1 = {}
for number in data:
if number not in dict1:
dict1[number] = 1
else:
dict1[number] += 1
tuple_data = dict1.items()
lst = sorted(tuple_data)
return(lst)
>>>[(1, 2), (2, 2), (3, 2), (4, 1), (5, 2)]
How would I sort it ascendingly by using the values instead of keys.
If you want to sort by the values(second item in each tuple), specify key:
sorted(tuple_data, key=lambda x: x[1])
Or with operator.itemgetter:
sorted(tuple_data, key=operator.itemgetter(1))
Also as a side note, your counting code:
dict1 = {}
for number in data:
if number not in dict1:
dict1[number] = 1
else:
dict1[number] += 1
Can be simplified with collections.Counter:
dict1 = collections.Counter(data)
With all the above in mind, your code could look like this:
from operator import itemgetter
from collections import Counter
def CountValues(data):
counts = Counter(data)
return sorted(counts.items(), key=itemgetter(1))
print(CountValues([1,2,3,1,2,3,5,5,4]))
# [(4, 1), (1, 2), (2, 2), (3, 2), (5, 2)]
You can use the sorted with the help of key parameter. it is not a in-place sorting . Thus it never modifies the original array.
for more
In [18]: data = [1,2,3,1,2,3,5,5,4]
In [19]: from collections import Counter
In [20]: x=Counter(data).items()
#Sorted OUTPUT
In [21]: sorted(list(x), key= lambda i:i[1] )
Out[21]: [(4, 1), (1, 2), (2, 2), (3, 2), (5, 2)]
In [22]: x
Out[22]: dict_items([(1, 2), (2, 2), (3, 2), (5, 2), (4, 1)])
"Sort" function uses first element of data.
To sort dictionary by its values you can use for-loop for values:
d={1:1,2:2,5:2,4:3,3:2}
x=[]
for i in set(sorted(d.values())):
for j in sorted(d.items()):
if j[1]==i:
x.append(j)
print(x)
if you don't convert sorted(d.values()) to set{} , it will check every value, even there are same numbers. For example if your values list is [1,2,2,3] , it will check items for value "2" two times and as a result your sorted list will contain repeated data which both have value "2" . But set{} keeps only one of each element and in this case, for-loop will check every different value of d.values() . And if there are items with a same value, code will sort them by keys because of sorted(d.items()) .
(to understand better you can use this code without that set{} and use d.items() instead of sorted(d.items()))

Python: Lists to Dictionary

I'm writing this question despite the many answers on stackoverflow as the solutions did not work for my problem.
I have 2 Lists, List1 and List2. When I dict(zip(List1,List2)) the order of the elements inside the dictionary are disturbed.
print s_key
print value
sorted_dict = {k: v for k,v in zip(s_key,value)}
another_test = dict(zip(s_key,value))
print sorted_dict
print another_test
print zip(s_key,value))
Terminal :
[2, 1, 3]
[31, 12, 5]
{1: 12, 2: 31, 3: 5}
{1: 12, 2: 31, 3: 5}
[(2, 31), (1, 12), (3, 5)]
I was under the impression that the [(2, 31), (1, 12), (3, 5)] would be converted to a dict
Any help to understand where or what I'm doing wrong would help! Thanks!
a=[2, 1, 3]
b=[31, 12, 5]
from collections import OrderedDict
print(OrderedDict(zip(a,b)))
You cannot sort a dictionary, in your case if you wanted to display sorted key/values of your dictionary you can convert it to a list of tuples as you have and sort it by whichever element you want. In the code below it creates a list of tuples and sorts by the first element in the tuples:
l1,l2=[2, 1, 3],[31, 12, 5]
print ([(one,two) for (one,two) in
sorted(zip(l1,l2),key=lambda pair: pair[0])])
prints:
[(1, 12), (2, 31), (3, 5)]
shoutout to Sorting list based on values from another list? for the help
Either that or create a list of the dictionaries keys and sort the list then loop through the list and call each key
Or use ordered dict as others have pointed out

How do I organise a nested list representing coordinate-values to a coordinate-list

I would like to change my data-structure that get from my data-files in such a way that I get a list of all coordinate-values for every coordinates (so a list for all coordinates filled with values)
e.g.
for i in range (files):
open file
file_output = [[0,4,6],[9,4,1],[2,5,3]]
second loop
file_output = [[6,1,8],[4,7,3],[3,7,0]]
to
coordinates = [[0,6],[4,1],[6,8],[9,4],[4,7],[1,3],[2,3],[5,7],[3,0]]
It should be noted that I use over 1000 files of this format, which I should merge.
You could also explore the built-in zip() function
>>> l = []
>>> for k,v in zip(a,b):
l.append(zip(k,v))
>>> print l
[[0,6],[4,1],[6,8],[9,4],[4,7],[1,3],[2,3],[5,7],[3,0]]
>>> a = [[0,4,6],[9,4,1],[2,5,3]]
>>> b = [[6,1,8],[4,7,3],[3,7,0]]
>>> from itertools import chain
>>> zip(chain(*a),chain(*b))
[(0, 6), (4, 1), (6, 8), (9, 4), (4, 7), (1, 3), (2, 3), (5, 7), (3, 0)]
>>>
This should be useful.
[zip(i,j) for i in a for j in b]
However it provides list of tuples, which should satisfy your needs.
If there will only be two lists, you can use this as well.
[[i, j] for i in a for j in b]

Making list of list oneliner -python

I have a list
l=[(1,2),(1,6),(3,4),(3,6),(1,4),(4,3)]
I want to return a list that contains lists by the first number in each tuple.
Something like this:
[[2,4,6],[4,6],[3]]
To make a program that iterates on list and writing a whole function that does it is easy.
I want to find a oneliner - python way of doing it.
Any ideas?
>>> from itertools import groupby
>>> from operator import itemgetter
>>> L = [(1,2), (1,6), (3,4), (3,6), (1,4), (4,3)]
>>> [[y for x, y in v] for k, v in groupby(sorted(L), itemgetter(0))]
[[2, 4, 6], [4, 6], [3]]
Explanation
This works by using itertools.groupby. groupby finds consecutive groups in an iterable, returning an iterator through key, group pairs.
The argument given to groupby is a key function, itemgetter(0) which is called for each tuple, returning the first item as the key to groupby.
groupby groups elements in their original order so if you want to group by the first number in the list, it must first be sorted so groupby can go through the first numbers in ascending order and actually group them.
>>> sorted(L)
[(1, 2), (1, 4), (1, 6), (3, 4), (3, 6), (4, 3)]
There is the sorted list where you can clearly see the groups that will be created if you look back to the final output. Now you can use groupby to show the key, group pairs.
[(1, <itertools._grouper object at 0x02BB7ED0>), (3, <itertools._grouper object at 0x02BB7CF0>), (4, <itertools._grouper object at 0x02BB7E30>)]
Here are the sorted items grouped by the first number. groupby returns the group for each key as an iterator, this is great and very efficient but for this example we will just convert it to a list to make sure it's working properly.
>>> [(k, list(v)) for k,v in groupby(sorted(L), itemgetter(0))]
[(1, [(1, 2), (1, 4), (1, 6)]), (3, [(3, 4), (3, 6)]), (4, [(4, 3)])]
That is almost the right thing but the required output shows only the 2nd number in the groups in each list. So the following achieves the desired result.
[[y for x, y in v] for k, v in groupby(sorted(L), itemgetter(0))]
l = [(1, 2), (1, 6), (3, 4), (3, 6), (1, 4), (4, 3)]
d = {}
for (k, v) in l:
d.setdefault(k, []).append(v)
print d.values()
I know it's not a one liner, but perhaps it's easier to read than a one liner.

Categories