Convert list of lists to unique dictionary in python - python

I have the following list of lists: [[100, 23], [101, 34], [102, 35] ... ]
How can i convert it to a dictionary like that: {100: 23, 101: 34, 102: 35 ... }
Here is what i tried:
myDict = dict(map(reversed, myList))
This code works, but it will give the opposite of what i want in the dictionary: {23: 100, 101:34..}

You can pass a list with this format to dict() and it will convert it for you.
myList = [[100, 23], [101, 34], [102, 35]]
myDict = dict(myList)
print(myDict)

According to docs page for dict()
. . . the positional argument must be an iterable object. Each item in the iterable must itself be an iterable with exactly two objects. The first object of each item becomes a key in the new dictionary, and the second object the corresponding value.
and here is an example for the same doc page:
...
>>> d = dict([('two', 2), ('one', 1), ('three', 3)])
returns a dictionary equal to {"one": 1, "two": 2, "three": 3}

L = []
A = {}
for x,y in L:
A[x] = y

Related

How do I index a dictionary that i have turned into a list

Basically i have turned a dictionary into a list. Now i want to get the first,second,third, and fourth value of the list by indexing. I do not know where i have made a mistake but it does not let me index.
I have tried
newcouples3 = remaining1.keys()
newcouple3 = newcouples3[2]
but then I get an error.
{'Couple3': 9, 'Couple4': 12, 'Couple5': 15, 'Couple6': 18}
newcouples3 = remaining1.keys()
newcouple3 = newcouples3[2]
I want to get the first,second,third, and fourth key in that list.
i get this error:
newcouple3 = newcouples3[2]
TypeError: 'dict_keys' object does not support indexing
That's because indexing works on list type and .keys() returns a dict_keys object which doesn't support indexing.
You could do the following:
>>> some_dict = {'a': 'foo', 'b': 'bar'}
>>> type(some_dict.keys())
<class 'dict_keys'>
>>> list(some_dict.keys())[0]
'a'
>>>
Calling dict.keys() returns a view object. You would need to turn it into a list first.
newcouples3 = list(remaining1.keys())
You can try like below:
myDict = {'Couple3': 9, 'Couple4': 12, 'Couple5': 15, 'Couple6': 18}
print(myDict)
myDictKeys = [ k for k in myDict ]
print(myDictKeys)
print(myDictKeys[1])
myDictValues = [ v for v in myDict.values() ]
print(myDictValues)
print(myDictValues[1])
Output:
{'Couple3': 9, 'Couple4': 12, 'Couple5': 15, 'Couple6': 18}
['Couple3', 'Couple4', 'Couple5', 'Couple6']
Couple4
[9, 12, 15, 18]
12

How to change list values in dictionary in python?

I have a dictionary like this,
{'A':[[1,30],[40,50],[60,79]]
'B':[[2,23],[26,43],[59,119]]
'C':[[1,100],[149,167],[199,250]]
... }
I had the MAX value which is 600. Is it possible to calculate the difference between each value in every list?
Finally, I can get a dictionary like this
{'A':[[31,39],[51,59],[80,600]]
'B':[[24,25],[44,58],[120,600]]
'C':[[101,148],[168,198],[251,600]]
...
}
Let me explain how final output comes.
The origin data is
'A':[[i1,i2],[i3,i4],[i5,i6]]
Max value is M,
For each list, final output will be like
'A':[[(i2)+1,(i3)-1],[(i4)+1,(i5)-1],[(i6)+1,M]]
It seems I need a for loop to get there. But I have no idea how to do this in dictionary.
You can try this:
d1 = {'A':[[1,30],[40,50],[60,79]],
'B':[[2,23],[26,43],[59,119]],
'C':[[1,100],[149,167],[199,250]]}
def split_l(iterable, n):
return [iterable[i:i+n] for i in range(0, len(iterable), n)]
d2 = {k:split_l([val + (-1)**idx for idx, val in enumerate(sum(v, [])[1:])] + [600], 2) for k,v in d1.items()}
Or in more readable way:
d2 = {}
for k, v in d1.items():
flat_v = sum(v, [])[1:]
for idx, __ in enumerate(flat_v):
flat_v[idx] += (-1)**idx
flat_v.append(600)
split_v = [flat_v[i:i+2] for i in range(0, len(flat_v), 2)]
d2[k] = split_v
Results:
import pprint
pprint.pprint(d2)
{'A': [[31, 39], [51, 59], [80, 600]],
'B': [[24, 25], [44, 58], [120, 600]],
'C': [[101, 148], [168, 198], [251, 600]]}
YOu can you itertools.chain
>>> from itertools import chain
>>> d = {'A':[[1,30],[40,50],[60,79]], 'B':[[2,23],[26,43],[59,119]],}
>>> for key in d:
... d[key] = zip(*[iter([each+((-1)**index) for index,each in enumerate(chain.from_iterable(d[key]))]+[600,])]*2)
...
>>> d
{'A': [(31, 39), (51, 59), (80, 600)], 'B': [(24, 25), (44, 58), (120, 600)]}
That is,
>>> chain.from_iterable(d['A'])
<itertools.chain object at 0x7f6a9dd69950>
>>> list(chain.from_iterable(d['A']))
[31, 39, 51, 59, 80, 600]
>>> iter(each for each in enumerate(chain.from_iterable(d[key])))
<generator object <genexpr> at 0x7f6a9dd804b0>
>>> zip(*[iter(each for each in enumerate(chain.from_iterable(d[key])))]*2)
[((0, 2), (1, 23)), ((2, 26), (3, 43)), ((4, 59), (5, 119))]
keep in mind that in python you can swap values of two variables this way:
a, b = b, a
so your problem can be solved like this:
def my_func(a_dict, max):
for row in a_dict.values():
row[0][0], row[0][1], row[1][0], row[1][1], row[2][0], row[2][1] = \
row[0][1]+1, row[1][0]-1, row[1][1]+1, row[2][0]-1, row[2][1]+1, max
One thing to notice is that there is no return .... dictionary is mutable, so any change to a_dict will retain.
After calling my_func, the dictionary passed to the function will contain the result.
update
#MaximTitarenko told me that the number of inner lists in each row(row=a list associated with a key of the dictionary)may vary.
so I wrote another script which works in that case:
def make_result(a_dict, max):
for row in a_dict.values():
for index in range(len(row)-1):
row[index][0] = row[index][1] + 1
row[index][1] = row[index+1][0] -1
row[-1][0] = row[-1][1] + 1
row[-1][1] = max

Python dict sorting based on two values in dict

I have a dictionairy that is build as
>> dict = {'foo':[20,15],'bar':[10,5],'is':[35,3],'a':[20,10],'word':[50,1]}
I want to find the key that has the highest of list value [0] and the lowest of value [1] .. (or an approximation of it) but its giving me a total brainfreeze
So for this example the desired result would be
>> 'word':[50,1]
It has been suggested I should more clearly define my paramaters: right now I'm looking to print the top 10 highest results from the [0] value as long as the second value remains below 5
Thank you for taking the time to read the question
You can use max function with a proper key function :
>>> max(dict.items(),key=lambda x: (x[1][0],-x[1][1]))
('word', [50, 1])
Note that in this case the priority of x[1][0] (max value) is more than second one,So for some dictionaries like following :
>>> dict = { 'foo': [35,5], 'word': [60, 25]}
It will returns :
('word', [60, 25])
You can also get items based on the difference of the values (which seems more close to what you want):
>>> dict = { 'foo': [70,5], 'word': [68,1]}
>>> max(dict.items(),key=lambda x: (x[1][0]-x[1][1]))
('word', [68, 1])
Try with below code. I am not sure whether it satisfies all your scenarios
dict = {'a': [20, 10], 'word': [50, 1], 'is': [35, 3], 'foo': [20, 15], 'bar': [10, 5]}
value = max(dict.values())
b = value[1]
for each in dict.values():
if value[0] == each[0] and each[1] < b:
value = each
print (dict.keys()[dict.values().index(value)],value)

Convert list to list of ids

Python 3.3:
What is the easiest way to obtain from the list:
input = ["A", 112, "apple", 74, 112]
following list:
output = [0, 1, 2, 3, 1]
That is, assign automatically incremented id starting from 0 to every unique entry, and convert the original list to the list of this ids.
I am aware, that I can obtain cheap the number of classes by
number_of_classes = len(set(input))
But how to create correctly ordered output?
You could use list comprehension to create a list of indexes of when the element first occurs in that list.
For an input list i = ["A", 112, "apple", 74, 112]:
>>> [i.index(value) for value in i]
[0, 1, 2, 3, 1]
In addition to #ajcr answer, which is fine for small lists, here is solution that has linerar computational complexity (while using list.index() has O(n^2)):
data = ["A", 112, "apple", 74, 112]
index = {val: i for i, val in reversed(list(enumerate(data)))}
indexes = [index[x] for x in data]
indexed = [(x, index[x]) for x in data]
print index
print indexes
print indexed
Just keep a another list with the keys and use the array.index() method to get the index of the item:
input = ["A", 112, "apple", 74, 112]
keys = []
output = []
for item in input:
if item not in keys:
keys.append(item)
output.append(keys.index(item))
print output
Using dictionary:
input = ["A", 112, "apple", 74, 112]
dictMap = dict((i[1],i[0]) for i in enumerate(set(input)))
print [dictMap[i] for i in input]
Output:
[0, 1, 3, 2, 1]
>>> input = ["A", 112, "apple", 74, 112]
>>> my_dict = {x:i for i,x in enumerate(sorted(set(input),key=input.index))} # need to as set dosent remember order
>>> my_dict
{'A': 0, 112: 1, 74: 3, 'apple': 2}
>>> [ my_dict[x] for x in input ]
[0, 1, 2, 3, 1]

Nested list with dictionary as content

Hi how can I loop through lst2 below, and get the dictionary elements in lst1 if the elements are a match.
lst1 = [[(10, 70, {'a': 0.30}),
(12, 82, {'b': 0.35})],
[(11, 140, {'c': 0.54}),
(99, 25, {'d': 0.57})]
]
lst2 = [[(10, 70), (32, 25),(12,82)],
[(1598, 6009), (11,140), (33,66), (99,25)]
]
ie compare lst2 and if lst2 is in lst1 print the dictionary.
outcome should look like so:
outcome = [[{'a': 0.30}, {'b':0.35}], [{'c': 0.54}, {'d':0.57}]]
Thanks
Sorry an update on this one would be if lst1 is not nested ie
lst1 = [(10, 70, {'a': 0.30}),
(12, 82, {'b': 0.35}),
(11, 140, {'c': 0.54}),
(99, 25, {'d': 0.57})
]
lst2 = [[(10, 70), (32, 25),(12,82)],
[(1598, 6009), (11,140), (33,66), (99,25)]
]
such that the same outcome will be arrived at
You can flatten lst1 and convert that to a dictionary with dictionary comprehension, so that the lookups will be faster. Once the dictionary is constructed, you just have to iterate lst2 and if the element is a key in the dictionary, then get the corresponding dictionary value.
from itertools import chain
d = {(item[0], item[1]):item[2] for item in chain.from_iterable(lst1)}
print d
# {(12,82):{'b':0.3}, (10,70):{'a':0.3}, (11,140):{'c':0.54}, (99,25):{'d':0.57}}
print [[d[item] for item in items if item in d] for items in lst2]
# [[{'a': 0.3}, {'b': 0.3}], [{'c': 0.54}, {'d': 0.57}]]
If the input is not nested, like in the updated question, you don't need chaining. You can simply do
d = {(item[0], item[1]):item[2] for item in lst1}
For each pair, create a dict for the elements from lst1 (for performance) and then check for each of the elements from lst2.
outcome = []
for lst_a, lst_b in zip(lst1, lst2):
lookup = {a[:-1]:a[-1] for a in lst_a}
outcome.append([lookup[b] for b in lst_b if b in lookup])
print outcome

Categories