How to implement associative array (not dictionary) in Python? - python

I trying to print out a dictionary in Python:
Dictionary = {"Forename":"Paul","Surname":"Dinh"}
for Key,Value in Dictionary.iteritems():
print Key,"=",Value
Although the item "Forename" is listed first, but dictionaries in Python seem to be sorted by values, so the result is like this:
Surname = Dinh
Forename = Paul
How to print out these with the same order in code or the order when items are appended in (not sorted by values nor by keys)?

You can use a list of tuples (or list of lists). Like this:
Arr= [("Forename","Paul"),("Surname","Dinh")]
for Key,Value in Arr:
print Key,"=",Value
Forename = Paul
Surname = Dinh
you can make a dictionary out of this with:
Dictionary=dict(Arr)
And the correctly sorted keys like this:
keys = [k for k,v in Arr]
Then do this:
for k in keys: print k,Dictionary[k]
but I agree with the comments on your question: Would it not be easy to sort the keys in the required order when looping instead?
EDIT: (thank you Rik Poggi), OrderedDict does this for you:
od=collections.OrderedDict(Arr)
for k in od: print k,od[k]

First of all dictionaries are not sorted at all nor by key, nor by value.
And basing on your description. You actualy need collections.OrderedDict module
from collections import OrderedDict
my_dict = OrderedDict([("Forename", "Paul"), ("Surname", "Dinh")])
for key, value in my_dict.iteritems():
print '%s = %s' % (key, value)
Note that you need to instantiate OrderedDict from list of tuples not from another dict as dict instance will shuffle the order of items before OrderedDict will be instantiated.

You can use collections.OrderedDict. It's available in python2.7 and python3.2+.

This may meet your need better:
Dictionary = {"Forename":"Paul","Surname":"Dinh"}
KeyList = ["Forename", "Surname"]
for Key in KeyList:
print Key,"=",Dictionary[Key]

'but dictionaries in Python are sorted by values' maybe I'm mistaken here but what game you that ideea? Dictionaries are not sorted by anything.
You would have two solutions, either keep a list of keys additional to the dictionary, or use a different data structure like an array or arrays.

I wonder if it is an ordered dict that you want:
>>> k = "one two three four five".strip().split()
>>> v = "a b c d e".strip().split()
>>> k
['one', 'two', 'three', 'four', 'five']
>>> v
['a', 'b', 'c', 'd', 'e']
>>> dx = dict(zip(k, v))
>>> dx
{'four': 'd', 'three': 'c', 'five': 'e', 'two': 'b', 'one': 'a'}
>>> for itm in dx:
print(itm)
four
three
five
two
one
>>> # instantiate this data structure from OrderedDict class in the Collections module
>>> from Collections import OrderedDict
>>> dx = OrderedDict(zip(k, v))
>>> for itm in dx:
print(itm)
one
two
three
four
five
A dictionary created using the OrderdDict preserves the original insertion order.
Put another way, such a dictionary iterates over the key/value pairs according to the order in which they were inserted.
So for instance, when you delete a key and then add the same key again, the iteration order is changes:
>>> del dx['two']
>>> for itm in dx:
print(itm)
one
three
four
five
>>> dx['two'] = 'b'
>>> for itm in dx:
print(itm)
one
three
four
five
two

As of Python 3.7, regular dicts are guaranteed to be ordered, so you can just do
Dictionary = {"Forename":"Paul","Surname":"Dinh"}
for Key,Value in Dictionary.items():
print(Key,"=",Value)

Related

Python - how to sort a list of tuples to a dictionary or equivalent?

Hi i have a list of tuples containing words and their respective categories.
Is there anyway that i can clump them into something like a dictionary ?
Sample Data:
Data = [('word1 word2 word3', 2),
('word4 word5 word6', 3),
('word7 word8 word9', 3),
('word10 word11 word12', 2),
('word13 word14 word15', 1)]
Expected Output:
Out = {'1': 'word13 word14 word15'
'2': 'word1 word2 word3', 'word10 word11 word12'
'3': 'word4 word5 word6', 'word7 word8 word9'}
Is it possible to sort it in this manner ? what functions should i use. please advice me as i have a big amount of data. above is just an example. Thank You
The desired output you have shown is not exactly valid. To achieve the closest valid thing, use a defaultdict with an empty list
new_dict = defaultdict(list)
for values, key in Data:
new_dict[key].append(values)
Python can easily convert an iterable of (key, value) pairs into a dictionary, and back. But it looks like your tuples are (value, key).
This is still not that difficult in Python, just use a dict comprehension to switch them.
{k: v for v, k in Data}
Traditionally, dictionaries are unordered sets of key/value pairs, but dicts in recent Python versions can remember their insertion order. This is standard in Python 3.7, but considered an implementation detail before that in CPython 3.6. (And before that, you'd have to use an OrderedDict instead.)
So, if you really want your keys in order you can sort on them first, like so
import operator
{k: v for v, k in sorted(Data, key=operator.itemgetter(1))}
The sorted builtin can transform its elements before comparing them using a key function. The itemgetter(1) operator is equivalent to lambda xs: xs[1]. This is what makes it possible to sort tuples by their second element.
You can group data on categories and then use an OrderedDict
from itertools import groupby
from collections import OrderedDict
# Sort the data on the categories
Data = sorted(Data, key = lambda x : x[1])
# Group the data on basis of categories
grouped = [(key, list(i for i,j in group)) for key, group in groupby(Data, key=lambda x: x[1])]
# Put it into a OrderedDict, keys sorted
out = OrderedDict(grouped)
print(out[2]) # prints ['word1 word2 word3', 'word10 word11 word12']
You can use a defaultdict here and then from there use sorted with a dict() constructor to create the dictionary back in order you desire
from collections import defaultdict
dd = defaultdict(list)
for v, k in data:
dd[k].append(v)
d = dict(sorted(dd.items(), key=lambda x: x[0]))
print(d)
# {1: ['word13 word14 word15'], 2: ['word1 word2 word3', 'word10 word11 word12'], 3: ['word4 word5 word6', 'word7 word8 word9']}

Create OrderedDict from dict with values of list type (in the order of list's values)

It is a bit hard for me to explain it in words, so I'll show an example:
What I have (data is a dict instance):
data = {'a':[4,5,3], 'b':[1,0,2], 'c':[6,7,8]}
What I need (ordered_data is an OrderedDict instance):
ordered_data = {'b':[0,1,2], 'a':[3,4,5], 'b':[6,7,8]}
The order of keys should be changed with respect to order of items in nested lists
tmp = {k:sorted(v) for k,v in data.items()}
ordered_data = OrderedDict((k,v) for k,v in sorted(tmp.items(), key=lambda i: i[1]))
First sort the values. If you don't need the original data, it's OK to do this in place, but I made a temporary variable.
key is a function that returns a key to be sorted on. In this case, the key is the second element of the item tuple (the list), and since lists are comparable, that's good enough.
You can use OrderedDict by sorting your items and the values :
>>> from operator import itemgetter
>>> from collections import OrderedDict
>>> d = OrderedDict(sorted([(k, sorted(v)) for k, v in data.items()], key=itemgetter(1)))
>>> d
OrderedDict([('b', [0, 1, 2]), ('a', [3, 4, 5]), ('c', [6, 7, 8])])
Usually, you should not worry about the data order in the dictionary itself, and instead, jsut order it when you retrieve the dictionary's contents (i.e.: iterate over it):
data = {'a':[4,5,3], 'b':[1,0,2], 'c':[6,7,8]}
for datum in sorted(data.items(), key=lambda item: item[1]):
...

Python - Splitting dictionary into dictionaries with the same values?

Say I have a dictionary with many items that have the same values; for example:
dict = {'hello':'a', 'goodbye':'z', 'bonjour':'a', 'au revoir':'z', 'how are you':'m'}
How would I split the dictionary into dictionaries (in this case, three dictionaries) with the same values? In the example, I want to end up with this:
dict1 = {'hello':'a', 'bonjour':'a'}
dict2 = {'goodbye':'z', 'au revoir':'z'}
dict3 = {'how are you':'m'}
You can use itertools.groupby to collect by the common values, then create dict objects for each group within a list comprehension.
>>> from itertools import groupby
>>> import operator
>>> by_value = operator.itemgetter(1)
>>> [dict(g) for k, g in groupby(sorted(d.items(), key = by_value), by_value)]
[{'hello': 'a', 'bonjour': 'a'},
{'how are you': 'm'},
{'goodbye': 'z', 'au revoir': 'z'}]
Another way without importing any modules is as follows:
def split_dict(d):
unique_vals = list(set(d.values()))
split_dicts = []
for i in range(len(unique_vals)):
unique_dict = {}
for key in d:
if d[key] == unique_vals[i]:
unique_dict[key] = d[key]
split_dicts.append(unique_dict)
return split_dicts
For each unique value in the input dictionary, we create a dictionary and add the key values pairs from the input dictionary where the value is equal to that value. We then append each dictionary to a list, which is finally returned.

removing key value pairs by matching values python

I am searching for periods "." in a dictionary and trying to delete the key/value pair if I find it
if "." in dict.values():
#delete key, value pair from the dictionary
I am sure this is very simple but I cannot seem to locate an explanation.
Thanks for your help.
Create a new dictionary without those unwanted values using dictionary comprehension. Here is an example of how to do it:
>>> old_dict = {'one': '.', 'two': 2, 'three':3, 'four':'.'}
>>> new_dict = {k:v for k,v in old_dict.iteritems() if not v == '.'}
>>> new_dict
{'three': 3, 'two': 2}
using iteritems instead of items avoids creating an intermediate list and improves performance.
If you don't want to copy your dictionary, (for example if the dictionary is large, or you have a reference to it elsewhere) then you should do it this way:
ks = [k for k in d if d[k]=='.']
for k in ks:
d.pop(k)
Create your list of keys to be removed ahead of time as shown above. You don't want to modify your dictionary while iterating over it.

Converting Dictionary to List? [duplicate]

This question already has answers here:
How can I convert a dictionary into a list of tuples?
(13 answers)
Closed 3 years ago.
I'm trying to convert a Python dictionary into a Python list, in order to perform some calculations.
#My dictionary
dict = {}
dict['Capital']="London"
dict['Food']="Fish&Chips"
dict['2012']="Olympics"
#lists
temp = []
dictList = []
#My attempt:
for key, value in dict.iteritems():
aKey = key
aValue = value
temp.append(aKey)
temp.append(aValue)
dictList.append(temp)
aKey = ""
aValue = ""
That's my attempt at it... but I can't work out what's wrong?
dict.items()
Does the trick.
Converting from dict to list is made easy in Python. Three examples:
>> d = {'a': 'Arthur', 'b': 'Belling'}
>> d.items()
[('a', 'Arthur'), ('b', 'Belling')]
>> d.keys()
['a', 'b']
>> d.values()
['Arthur', 'Belling']
Your problem is that you have key and value in quotes making them strings, i.e. you're setting aKey to contain the string "key" and not the value of the variable key. Also, you're not clearing out the temp list, so you're adding to it each time, instead of just having two items in it.
To fix your code, try something like:
for key, value in dict.iteritems():
temp = [key,value]
dictlist.append(temp)
You don't need to copy the loop variables key and value into another variable before using them so I dropped them out. Similarly, you don't need to use append to build up a list, you can just specify it between square brackets as shown above. And we could have done dictlist.append([key,value]) if we wanted to be as brief as possible.
Or just use dict.items() as has been suggested.
You should use dict.items().
Here is a one liner solution for your problem:
[(k,v) for k,v in dict.items()]
and result:
[('Food', 'Fish&Chips'), ('2012', 'Olympics'), ('Capital', 'London')]
or you can do
l=[]
[l.extend([k,v]) for k,v in dict.items()]
for:
['Food', 'Fish&Chips', '2012', 'Olympics', 'Capital', 'London']
>>> a = {'foo': 'bar', 'baz': 'quux', 'hello': 'world'}
>>> list(reduce(lambda x, y: x + y, a.items()))
['foo', 'bar', 'baz', 'quux', 'hello', 'world']
To explain: a.items() returns a list of tuples. Adding two tuples together makes one tuple containing all elements. Thus the reduction creates one tuple containing all keys and values and then the list(...) makes a list from that.
Probably you just want this:
dictList = dict.items()
Your approach has two problems. For one you use key and value in quotes, which are strings with the letters "key" and "value", not related to the variables of that names. Also you keep adding elements to the "temporary" list and never get rid of old elements that are already in it from previous iterations. Make sure you have a new and empty temp list in each iteration and use the key and value variables:
for key, value in dict.iteritems():
temp = []
aKey = key
aValue = value
temp.append(aKey)
temp.append(aValue)
dictList.append(temp)
Also note that this could be written shorter without the temporary variables (and in Python 3 with items() instead of iteritems()):
for key, value in dict.items():
dictList.append([key, value])
If you're making a dictionary only to make a list of tuples, as creating dicts like you are may be a pain, you might look into using zip()
Its especialy useful if you've got one heading, and multiple rows. For instance if I assume that you want Olympics stats for countries:
headers = ['Capital', 'Food', 'Year']
countries = [
['London', 'Fish & Chips', '2012'],
['Beijing', 'Noodles', '2008'],
]
for olympics in countries:
print zip(headers, olympics)
gives
[('Capital', 'London'), ('Food', 'Fish & Chips'), ('Year', '2012')]
[('Capital', 'Beijing'), ('Food', 'Noodles'), ('Year', '2008')]
Don't know if thats the end goal, and my be off topic, but it could be something to keep in mind.

Categories