Swap position of keys in a dictionary for same value - python

I have a dictionary
cost = {
(0,1):70,
(0,2):40,
(1,2):65
}
I would like a dictionary where the values for the opposite keys are also the same. To clarify,
(0,1):70 is also the same as (1,0):70
I tried to flip the values of the keys using this:
for i,j in cost.keys():
cost [j,i]==cost[i,j]
This gives a key error of (1,0) but that is the key that I want the code to add.
I further tried cost1 = {tuple(y): x for x, y in cost.keys()}
This resulted in a TypeError:'int' object not iterable
How can I then further append all the values to a dictionary? Thank you for your time and help.

Try this code snippet, to see if that's what you want:
# make a new dict to reflect the swap keys:
cost1 = {}
for key, val in cost.items():
x, y = key # unpack the key
cost1[(y, x)] = val # swap x, y - tuple as the new key
print(cost1)
# {(1, 0): 70, (2, 0): 40, (2, 1): 65}

Related

Looping through a list adding values to dictionaries

I have a list of 4 dictionaries. I also have a list of 36 values. I'm trying to loop through the list of dictionaries, filling each dictionary with the list values in ascending order having item 1 as the key, 2 & 3 as the value attached and so on. The final result being 4 dictionaries, each with three keys and each key having two values attached.
The end result would be
dict1={x:(7,4),y:(7,8),z:(7:22)}
dict2={x: (111,4),y:(111,8),z:(111:22)}
...
Currently I have the following which does not work.
my_list = ['x',7,4,'y',7,8,'z',7,22,'x',111,4,'y',111,8,'z',111,22 and so on]
dict1={}
dict2={}
dict3={}
dict4={}
my_dict_list=[dict1,dict2,dict3,dict4]
for dicts in my_dict_list:
for x in range (0,len(my_list),3):
dicts[my_list[x]] = my_list[x+1],my_list[x+2]
break
the output of that code being the first 3 items in my list, in all four of the dictionaries. As so:
>>> dict_1
{'x': (7, 4)}
>>> dict_2
{'x': (7, 4)}
>>> dict_3
{'x': (7, 4)}
>>> dict_4
{'x': (7, 4)}
I think this is the closest I've got so far as it is actually filling each dictionary, previously I've only managed to fill the first dictionary and other similar wrong scenarios. Can anyone help or point me in the right direction?
Try this:
my_list = ['x',7,4,'y',7,8,'z',7,22,'x',111,4,'y',111,8,'z',111,22]
my_dict_list = []
idx = 0
current_dict = {}
while idx < len(my_list):
key, *vals = my_list[idx : idx + 3]
# If key repeats, starting a new current_dict, old one adding to my_dict_list
if key in current_dict:
my_dict_list.append(current_dict)
current_dict = {}
current_dict[key] = vals
idx += 3
if current_dict:
my_dict_list.append(current_dict)
print(my_dict_list)
In the solution above we loop my_list reading 3 values at a time. And in case if key of a dictionary is repeated this is interpreted and a starting of a new dictionary so the old one must be stored in my_dict_list.

Python: List of pairs. Making every pair single and sum the values of the same keys

I have a list of pairs.The list contains items of [x,y].I would like to make list or dictionary making the left item the key and right the value.The list maybe contains multiple times the same key. I want to sum the values and keep one time the key.
E.x
pairs[0]=['3106124650', 2.86]
pairs[1]=['3106124650', 8.86]
pairs[2]=['5216154610', 23.77]
I want to keep '3106124650' one time and sum the values.So my new list or dictionary will contain one time this key with value 11.72.
'3106124650',11.72
Here's a way. For large datasets, numpy will probably be faster though.
import collections
result = collections.defaultdict(lambda : 0)
for k,v in pairs:
result[k]+=v
sumdict = dict()
for i, v in pairs:
sumdict[i] = v + sumdict.get(i, 0)
li=[['a',1],['a',2],['b',3],['c',4]]
d={}
for w in li:
d[w[0]]=w[1]+d.get(w[0],0)
Output:{'a': 3, 'b': 3, 'c': 4}
you can try this:
d={}
for entry in pairs:
if entry[0] in d:
d[entry[0]]+=entry[1]
else:
d[entry[0]]=entry[1]

How to store key value pairs

I want to store key-value pairs, but I don't know how to do it.
What I want to achieve is a variable that would store the different value pairs.
What I would want is something like this:
dic = {}
valuepair = (2,3), "cell1"
Each value pair is unique and I would want to be able to do something like this:
dic[(2,3)] = "cell1"
dic["cell1"] = (2,3)
Is there a way to achieve something like that for many different unique value pairs?
If you ask if you can use a tuple as a key - yes, for example:
dic[(2,3)] = "cell1"
print(dic[(2,3)])
would show cell1
or create an inverse dict like this:
inverse_d = {v:k for key, value in d}
Key-Value pair means a key mapped to a value. And what you are doing is right, but if you got the key, you can get value from it. So you need not store value ("cell1"), again as a key, when it is already a value. Sorry, if I don't get your question. Or you can do this too:
x = [("k1","v1"),("k2,"v2")]
d = dict(x)
print(d)
OUTPUT : {"k1":"v1", "k2":"v2"}
You can always do that, but why would you need that is still a question.
valuepairs = [[(2,3), "cell1"], [(4,5), "cell2"]]
dic = {}
for x, y in valuepairs:
dic[x] = y
dic[y] = x
print(dic)
# {(2, 3): 'cell1', 'cell1': (2, 3), (4, 5): 'cell2', 'cell2': (4, 5)}

Python - Get key of specific tuple index minimum in dictionary of tuples

I have a dict of tuples such as:
d = {'a': (3, 5), 'b': (5, 8), 'c': (9, 3)}
I want to return the key of the minimum of the tuple values based on the tuple index. For example, if using tuple index = 0, then 'a' would be returned. if index = 1, then 'c' would be returned. I have tried using min(), for example
min(d, key=d.get)
but am not sure how to manipulate it to select the tuple index to use. Although there are similar questions, I have not found an answer to this. Apologies in advance if this is a duped question, and please link to the answer. Thanks
You can write a lambda function to get the elements from the value by their index:
min(d, key=lambda k: d[k][0])
# 'a'
min(d, key=lambda k: d[k][1])
# 'c'
Since multiple keys could have the same value, you might want to return a list of matching keys, not just a single key.
def min_keys(d, index):
# Initialize lists
values = []
matches = []
# Append tuple items to list based on index
for t in list(d.values()):
values.append(t[index])
# If the item matches the min, append the key to list
for key in d:
if d[key][index] == min(values):
matches.append(key)
# Return a list of all keys with min value at index
return matches
Dictionaries are unsorted and have no index.
If you want the return the key alphabetically first you could use the ascii order:
print(chr(min([ord(key) for key in d.keys()])))
Here's a portable method you can use for dicts with a structure like yours, and feel free to choose the index of interest in the tuple:
def extract_min_key_by_index(cache, index):
min_val = float('inf')
min_key = 0
for k, v in d.iteritems():
if v[index] < min_val:
min_key, min_val = k, v[index]
return min_key
d = {'a': (3, 5), 'b': (5, 8), 'c': (9, 3)}
INDEX = 0
print extract_min_key_by_index(d, INDEX)

retrieving keys from dictionaries depending on value in python

I'm trying to find the most efficient way in python to create a dictionary of 'guids' (point ids in rhino) and retrieve them depending on the value(s) I assign them, change that value(s) and restoring them back in the dictionary. One catch is that with Rhinoceros3d program the points have a random generated ID number which I don't know so I can only call them depending on the value I give them.
are dictionaries the correct way? should the guids be the value instead of the keys?
a very basic example :
arrPts=[]
arrPts = rs.GetPoints() # ---> creates a list of point-ids
ptsDict = {}
for ind, pt in enumerate(arrPts):
ptsDict[pt] = ('A'+str(ind))
for i in ptsDict.values():
if '1' in i :
print ptsDict.keys()
how can I make the above code print the key that has the value '1' , instead of all the keys? and then change the key's value from 1 to e.g. 2 ?
any help also on the general question would be appreciated to know I'm in the right direction.
Thanks
Pav
You can use dict.items().
An example:
In [1]: dic={'a':1,'b':5,'c':1,'d':3,'e':1}
In [2]: for x,y in dic.items():
...: if y==1:
...: print x
...: dic[x]=2
...:
a
c
e
In [3]: dic
Out[3]: {'a': 2, 'b': 5, 'c': 2, 'd': 3, 'e': 2}
dict.items() returns a list of tuples containing keys and value pairs in python 2.x:
In [4]: dic.items()
Out[4]: [('a', 2), ('c', 2), ('b', 5), ('e', 2), ('d', 3)]
and in python 3.x it returns an iterable view instead of list.
I think you want the GUID's to be values, not keys, since it looks like you want to look them up by something you assign. ...but it really depends on your use case.
# list of GUID's / Rhinoceros3d point ids
arrPts = ['D20EA4E1-3957-11d2-A40B-0C5020524153',
'1D2680C9-0E2A-469d-B787-065558BC7D43',
'ED7BA470-8E54-465E-825C-99712043E01C']
# reference each of these by a unique key
ptsDict = dict((i, value) for i, value in enumerate(arrPts))
# now `ptsDict` looks like: {0:'D20EA4E1-3957-11d2-A40B-0C5020524153', ...}
print(ptsDict[1]) # easy to "find" the one you want to print
# basically make both keys: `2`, and `1` point to the same guid
# Note: we've just "lost" the previous guid that the `2` key was pointing to
ptsDict[2] = ptsDict[1]
Edit:
If you were to use a tuple as the key to your dict, it would look something like:
ptsDict = {(loc, dist, attr3, attr4): 'D20EA4E1-3957-11d2-A40B-0C5020524153',
(loc2, dist2, attr3, attr4): '1D2680C9-0E2A-469d-B787-065558BC7D43',
...
}
As you know, tuples are immutable, so you can't change the key to your dict, but you can remove one key and insert another:
oldval = ptsDict.pop((loc2, dist2, attr3, attr4)) # remove old key and get value
ptsDict[(locx, disty, attr3, attr4)] = oldval # insert it back in with a new key
In order to have one key point to multiple values, you'd have to use a list or set to contain the guids:
{(loc, dist, attr3, attr4): ['D20E...', '1D2680...']}

Categories

Resources