Convert a dict to tuple preserving order [duplicate] - python

This question already has answers here:
Converting dict to OrderedDict
(5 answers)
Closed 5 years ago.
I have a dictionary, this is a example dict it can have any number of fields
{'name': 'satendra', 'occupation': 'engineer', 'age': 27}
How can i convert this to tuple so that it will result ordered list of tuple.
# Expected output
[('name', 'satendra'), ('occupation', 'engineer'), ('age', 27)]
UPDATE
OrderedDict are useful when ordered list of tuple passed to it not for a JSON object, so i guess this is not a duplicate

Like you already understood from the comments, there is no order to preserve since there is no order to begin with. This JSON may arrive from the server in any arbitrary order.
However, if you know the keys you are interested in you can construct the list of tuples yourself.
Note that this code iterates over a separate tuple of keys in a known order. You will have to maintain that tuple manually.
relevant_keys = ('name', 'occupation', 'age')
data = {'occupation': 'engineer', 'age': 27, 'name': 'satendra'}
list_of_tuples = [(key, data[key]) for key in relevant_keys]
print(list_of_tuples)
# [('name', 'satendra'), ('occupation', 'engineer'), ('age', 27)]

Use OrderedDict() as suggested in comments, but correctly:
from collections import OrderedDict
d = OrderedDict([('name', 'satendra'), ('occupation', 'engineer'), ('age', 27)])
You define it as you would like your output to be. Then you use it as you would normal dictionary.
And when you want your list of tuples back, you do:
t = d.items()
You can use this solution when you know what keys to expect and you cannot use OrderedDict():
def sortdict (d, keys=["name", "occupation"]):
mx = len(keys)
def customsortkey (key):
try: return keys.index(key)
except: return mx
kys = sorted(d, key=customsortkey)
return [(key, d[key]) for key in kys]
This function will sort everything in the input dictionary "d" according to the order set by "keys" list. Any item in the dictionary, without its key present in list "keys" will be put to the end of the output in arbitrary order. You can indicate keys that aren't present in the dictionary,
The output will be a list of tuples (key, value) as you require.
This is one of possible solutions and it is far from ideal. I.e. we can start a discussion about its efficiency and overhead. But really, in practice it will work just fine, and will handle any unexpected keys nicely.
More efficient version of this function would be to use a dictionary to denote the order of keys instead of the list. A dictionary having the key in question for a key and an sorting index for its value.
Like this:
def sortdict (d, keys={"name": 0, "occupation": 1}):
mx = len(keys)
kys = sorted(d, key=lambda k: keys.get(k, mx))
return [(key, d[key]) for key in kys]

MyDict = {'name': 'satendra', 'occupation': 'engineer', 'age': 27}
MyList = []
For key in MyDict:
MyList.append( (key,MyDict[key]) )
Now MyList is a list of tuples.

Related

Iterating over part of dictionary keys

I'm new to Python and I'm wondering how can I iterate over part of the keys in a list of dictionaries.
Suppose I have something like:
OrderedDict([('name', 'Anna'), ('AAA', '15'), ('BBB', '49'), ('CCC', '38')])
OrderedDict([('name', 'Bob'), ('AAA', '31'), ('BBB', '21'), ('CCC', '41')])
etc.
I need to retrieve and iterate over AAA, BBB, CCC (keys, not values), but:
only one time (not repeating for every dict in the list, but once, e.g. only for Anna)
skipping 'name', just those going after
in reality, I have many more of these keys (more than 10), so the question is how to iterate and not hard code it
I'd be very glad if you could help
Thanks a lot!
Just iterate over the first list, and check if it's name so you can skip it.
for key in list_of_dicts[0]:
if key != 'name':
print(key)
You can extract the keys from the first row by using:
keys = (key for key in list_of_dicts[0] if key != 'name')
Now you can iterate through the keys using something like:
for var in keys:
print(var)
I'm not sure if it's the best way, but I'd do it like this:
Dict = OrderedDict([('name', 'Anna'), ('AAA', '15'), ('BBB', '49'), ('CCC', '38')])
keys = [] # keys is an empty list
for i in Dict: # Iterate over all keys in the dictionary
if i != 'name': # Exclude 'name' from the list
keys.append(i) # Append each 'i' to the list
That will get you a list, keys, of each of the keys in Dict, excluding 'name'.
You can now iterate over the keys like this:
for i in keys:
print(i) # Do something with each key
And if you want to iterate over the values as well:
for i in keys:
print(Dict[i]) # Do something with each value
You would use a for loop. Here is an example (I called i since I do not know what you call the argument of that function):
i = [('name', 'Anna'), ('AAA', '15'), ('BBB', '49'), ('CCC', '38')]
for a in range(len(i)):
print(i[a][1])
The above gets the index of a, and inside the tuple (which has 2 elements so 0 or 1) gets the 2nd index.
NOTE:
You might want to make a nested for loop to get the ideals within the tuple.
Here is what you can do:
lst = [{...}, {...}, {...}, {...}, ...]
f = ['name']
for d in lst: # For every dict in the list
for k in d: # For every key in the dict
if k not in f: # If the key is not in the list f
# Do something
f.append(k) # Add that key to f so the program won't iterate through it again
UPDATE
(I just found out that every dict has the same keys, so there's no need to do all this checking):
lst = [{...}, {...}, {...}, {...}, ...]
for d in lst: # For every dict in the list
for k in d: # For every key in the dict
if k != 'name': # If the key is not 'name'
# Do something

Python: Accessing individual values in a dictionary of a list of tuples [duplicate]

This question already has answers here:
Query Python dictionary to get value from tuple
(3 answers)
Closed 6 years ago.
I have a dictionary in Python where each key has a set of ten tuples. I am trying to iterate through the dictionary access the individual elements within each tuple- how should I go about that?
The dictionary looks like this:
{'Key1': [(Hi, 1), (Bye, 2)], 'Key2': [(Cats, Blue), (Dogs, Red)]}
Say I want vectors of the Keys, a vectors of the first elements [Hi, Bye, Cats, Dogs] and one of the second [1,2, Blue, red]
This is the code I was attempting:
for key in dict:
for tuplelist in dict:
key_vector.append(key_
tuple1_vector.append(dict[key[1]])
tuple2_vector.append(dict[key[2]])
I know this is incorrect but I am not sure how to go about fixing it.
I assume you mean your dict is:
your_dict = {'Key1': [('Hi', 1), ('Bye', 2)], 'Key2': [('Cats', 'Blue'), ('Dogs', 'Red')]}
You can iterate over all the keys, get whatever tuple is in there, and then iterate over all the entries inside that tuple. There probably is an easier way but this should at least get you there:
for key in your_dict:
for t in your_dict[key]:
for i in t:
print(i)
You can use .values() to access the values in the dictionary, then iterate over the values lists and index the respective items in the tuple:
tuple1_vector = []
tuple2_vector = []
for v in d.values():
for t in v:
tuple1_vector.append(t[0])
tuple2_vector.append(t[1])
You can also do this with a list comprehension:
tuple1_vector = [t[0] for v in d.values() for t in v]
tuple2_vector = [t[1] for v in d.values() for t in v]
print(tuple1_vector)
# ['Cats', 'Dogs', 'Hi', 'Bye']
print(tuple2_vector)
# ['Blue', 'Red', 1, 2]
You could do the following:
keys = []
tuple1 = []
tuple2 = []
for key in dict:
keys.append(key)
tuple1.append(dict[key][0][0])
tuple1.append(dict[key][0][1])
tuple1.append(dict[key][1][0])
tuple1.append(dict[key][1][1])
But do not, this is really bad code. I'm just showing a solution but that's not worth it. The other guys have made it better (such as iterating over dict[key] (e.g. for item in dict[key]...) .

How to reorder a python ordered dict based on array?

Say I have an Ordered Dict with the following items:
mydict = {'Rust': {'definition':'rusts definition'}, 'Iron': {'definition:'iron definition'}, 'Pyrite': {'definition':'pyrite definition'}}
If I have an array:
myorder = ['Pyrite', 'Rust', 'Iron']
How can I reorder the Ordered Dict such that the items in mydict are ordered based on myorder?
Try this:
mydict = {'Rust': {'definition':'rusts definition'},
'Iron': {'definition':'iron definition'},
'Pyrite': {'definition':'pyrite definition'}}
myorder = ['Pyrite', 'Rust', 'Iron']
from collections import OrderedDict
ordered = OrderedDict()
for k in myorder:
ordered[k] = mydict[k]
Or even shorter:
ordered = OrderedDict((k, mydict[k]) for k in myorder)
Using the above snippet, ordered will contain the same keys/values as mydict, but they'll be inserted in the same order specified by myorder. That's the advantage of OrderedDict: when iterating over it, it'll preserve the insertion order.
There's no way to sort the existing dictionary in-place (well, you could extract all the key-value pairs, eliminate them and add them again in the correct order, but that's not the idea, is it?), it's necessary to create a new one ... or simply iterate over the existing dictionary in the specified order:
for k in myorder:
x = mydict[k] # do something with x
If you would like to use them in that order, you can do this, for example.
for key in myorder:
value = mydict[key]
print value
Outputs:
{'definition': 'pyrite definition'}
{'definition': 'rusts definition'}
{'definition': 'iron definiti

sort dict by value python [duplicate]

This question already has answers here:
How do I sort a dictionary by value?
(34 answers)
Closed 3 years ago.
Assume that I have a dict.
data = {1:'b', 2:'a'}
And I want to sort data by 'b' and 'a' so I get the result
'a','b'
How do I do that?
Any ideas?
To get the values use
sorted(data.values())
To get the matching keys, use a key function
sorted(data, key=data.get)
To get a list of tuples ordered by value
sorted(data.items(), key=lambda x:x[1])
Related: see the discussion here: Dictionaries are ordered in Python 3.6+
If you actually want to sort the dictionary instead of just obtaining a sorted list use collections.OrderedDict
>>> from collections import OrderedDict
>>> from operator import itemgetter
>>> data = {1: 'b', 2: 'a'}
>>> d = OrderedDict(sorted(data.items(), key=itemgetter(1)))
>>> d
OrderedDict([(2, 'a'), (1, 'b')])
>>> d.values()
['a', 'b']
From your comment to gnibbler answer, i'd say you want a list of pairs of key-value sorted by value:
sorted(data.items(), key=lambda x:x[1])
Thanks for all answers.
You are all my heros ;-)
Did in the end something like this:
d = sorted(data, key = data.get)
for key in d:
text = data[key]
Sort the values:
sorted(data.values())
returns
['a','b']
I also think it is important to note that Python dict object type is a hash table (more on this here), and thus is not capable of being sorted without converting its keys/values to lists. What this allows is dict item retrieval in constant time O(1), no matter the size/number of elements in a dictionary.
Having said that, once you sort its keys - sorted(data.keys()), or values - sorted(data.values()), you can then use that list to access keys/values in design patterns such as these:
for sortedKey in sorted(dictionary):
print dictionary[sortedKeY] # gives the values sorted by key
for sortedValue in sorted(dictionary.values()):
print sortedValue # gives the values sorted by value
Hope this helps.
You could created sorted list from Values and rebuild the dictionary:
myDictionary={"two":"2", "one":"1", "five":"5", "1four":"4"}
newDictionary={}
sortedList=sorted(myDictionary.values())
for sortedKey in sortedList:
for key, value in myDictionary.items():
if value==sortedKey:
newDictionary[key]=value
Output: newDictionary={'one': '1', 'two': '2', '1four': '4', 'five': '5'}
In your comment in response to John, you suggest that you want the keys and values of the dictionary, not just the values.
PEP 256 suggests this for sorting a dictionary by values.
import operator
sorted(d.iteritems(), key=operator.itemgetter(1))
If you want descending order, do this
sorted(d.iteritems(), key=itemgetter(1), reverse=True)
no lambda method
# sort dictionary by value
d = {'a1': 'fsdfds', 'g5': 'aa3432ff', 'ca':'zz23432'}
def getkeybyvalue(d,i):
for k, v in d.items():
if v == i:
return (k)
sortvaluelist = sorted(d.values())
sortresult ={}
for i1 in sortvaluelist:
key = getkeybyvalue(d,i1)
sortresult[key] = i1
print ('=====sort by value=====')
print (sortresult)
print ('=======================')

index python dictionary by value [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Inverse dictionary lookup - Python
Is there a built in way to index a dictionary by value in Python.
e.g. something like:
dict = {'fruit':'apple','colour':'blue','meat':'beef'}
print key where dict[key] == 'apple'
or:
dict = {'fruit':['apple', 'banana'], 'colour':'blue'}
print key where 'apple' in dict[key]
or do I have to manually loop it?
You could use a list comprehension:
my_dict = {'fruit':'apple','colour':'blue','meat':'beef'}
print [key for key, value in my_dict.items() if value == 'apple']
The code above is doing almost exactly what said you want:
print key where dict[key] == 'apple'
The list comprehension is going through all the key, value pairs given by your dictionary's items method, and making a new list of all the keys where the value is 'apple'.
As Niklas pointed out, this does not work when your values could potentially be lists. You have to be careful about just using in in this case since 'apple' in 'pineapple' == True. So, sticking with a list comprehension approach requires some type checking. So, you could use a helper function like:
def equals_or_in(target, value):
"""Returns True if the target string equals the value string or,
is in the value (if the value is not a string).
"""
if isinstance(target, str):
return target == value
else:
return target in value
Then, the list comprehension below would work:
my_dict = {'fruit':['apple', 'banana'], 'colour':'blue'}
print [key for key, value in my_dict.items() if equals_or_in('apple', value)]
You'll have to manually loop it, but if you'll need the lookup repeatedly this is a handy trick:
d1 = {'fruit':'apple','colour':'blue','meat':'beef'}
d1_rev = dict((v, k) for k, v in d1.items())
You can then use the reverse dictionary like this:
>>> d1_rev['blue']
'colour'
>>> d1_rev['beef']
'meat'
Your requirements are more complex than you realize:
You need to handle both list values and plain values
You don't actually need to get back a key, but a list of keys
You could solve this in two steps:
normalize the dict so that every value is a list (every plain value becomes a single-element)
build a reverse dictionary
The following functions will solve this:
from collections import defaultdict
def normalize(d):
return { k:(v if isinstance(v, list) else [v]) for k,v in d.items() }
def build_reverse_dict(d):
res = defaultdict(list)
for k,values in normalize(d).items():
for x in values:
res[x].append(k)
return dict(res)
To be used like this:
>>> build_reverse_dict({'fruit':'apple','colour':'blue','meat':'beef'})
{'blue': ['colour'], 'apple': ['fruit'], 'beef': ['meat']}
>>> build_reverse_dict({'fruit':['apple', 'banana'], 'colour':'blue'})
{'blue': ['colour'], 'apple': ['fruit'], 'banana': ['fruit']}
>>> build_reverse_dict({'a':'duplicate', 'b':['duplicate']})
{'duplicate': ['a', 'b']}
So you just build up the reverse dictionary once and then lookup by value and get back a list of keys.

Categories

Resources