preresult is an OrderedDict().
I want to save the first 100 elements in it. Or keep preresult but delete everything other than the first 100 elements.
The structure is like this
stats = {'a': {'email1':4, 'email2':3},
'the': {'email1':2, 'email3':4},
'or': {'email1':2, 'email3':1}}
Will islice work for it? Mine tells itertool.islice does not have items
Here's a simple solution using itertools:
>>> import collections
>>> from itertools import islice
>>> preresult = collections.OrderedDict(zip(range(200), range(200)))
>>> list(islice(preresult, 100))[-10:]
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
This returns only keys. If you want items, use iteritems (or just items in Python 3):
>>> list(islice(preresult.iteritems(), 100))[-10:]
[(90, 90), (91, 91), (92, 92), (93, 93), (94, 94), (95, 95), (96, 96), (97, 97), (98, 98), (99, 99)]
You can slice the keys of OrderedDict and copy it.
from collections import OrderedDict
a = OrderedDict()
for i in xrange(10):
a[i] = i*i
b = OrderedDict()
for i in a.keys()[0:5]:
b[i] = a[i]
b is a sliced version of a
for k, v in list(od.items())[:100]:
pass
Can't we just convert the list into a dictionary with keys and values, then slide it as you need, then put it back into an orderedDict?
Here's how I did it.
from collections import OrderedDict
#defined an OrderedDict()
stats = OrderedDict()
#loading the ordered list with 100 keys
for i in range(100):
stats[str(i)] = {'email'+str(i):i,'email'+str(i+1):i+1}
#Then slicing the first 20 elements from the OrderedDict
#I first convert it to a list, then slide, then put it back as an OrderedDict
st = OrderedDict(list(stats.items())[:20])
print (stats)
print (st)
The output of this will be as follows. I reduced the first one to 10 items and sliced it to only the first 5 items:
OrderedDict([('0', {'email0': 0, 'email1': 1}), ('1', {'email1': 1, 'email2': 2}), ('2', {'email2': 2, 'email3': 3}), ('3', {'email3': 3, 'email4': 4}), ('4', {'email4': 4, 'email5': 5}), ('5', {'email5': 5, 'email6': 6}), ('6', {'email6': 6, 'email7': 7}), ('7', {'email7': 7, 'email8': 8}), ('8', {'email8': 8, 'email9': 9}), ('9', {'email9': 9, 'email10': 10})])
OrderedDict([('0', {'email0': 0, 'email1': 1}), ('1', {'email1': 1, 'email2': 2}), ('2', {'email2': 2, 'email3': 3}), ('3', {'email3': 3, 'email4': 4}), ('4', {'email4': 4, 'email5': 5})])
I did a print (dict(st)) to get this:
{'0': {'email0': 0, 'email1': 1}, '1': {'email1': 1, 'email2': 2}, '2': {'email2': 2, 'email3': 3}, '3': {'email3': 3, 'email4': 4}, '4': {'email4': 4, 'email5': 5}}
Related
Have a list of dictionaries, something like this:
l = [{'a':25}, {'a':25}, {'b':30}, {'c':200}, {'b':30}]
want to find the distinct elements and their corresponding indices, something like this:
[
({'a':25}, [0,1]),
({'b':30}, [2,4]),
({'c':200}, [3]),
]
tried with itertools.groupby, but couldn't make it happen, perhaps I'm missing something, any other directions are great too.
Consider this list of dictionaries:
>>> dicts
[{'a': 3},
{'d': 4, 'a': 3, 'c': 1},
{'d': 8, 'c': 0, 'b': 9},
{'c': 3, 'a': 9},
{'a': 5, 'd': 8},
{'d': 5, 'b': 5, 'a': 0},
{'b': 7, 'c': 7},
{'d': 6, 'b': 7, 'a': 6},
{'a': 4, 'c': 1, 'd': 5, 'b': 2},
{'d': 7}]
Assuming you want all indices of every instance of every dictionary's keys:
idxs = {}
for i, d in enumerate(l):
for pair in d.items():
idxs.setdefault(pair, []).append(i)
This produces what I would consider more useful output, as it allows you to look up the indices of any specific key-value pair:
{('a', 3): [0, 1],
('d', 4): [1],
('c', 1): [1, 8],
('d', 8): [2, 4],
('c', 0): [2],
('b', 9): [2],
('c', 3): [3],
('a', 9): [3],
('a', 5): [4],
('d', 5): [5, 8],
('b', 5): [5],
('a', 0): [5],
('b', 7): [6, 7],
('c', 7): [6],
('d', 6): [7],
('a', 6): [7],
('a', 4): [8],
('b', 2): [8],
('d', 7): [9]}
However, if you must convert to List[Tuple[Dict[str, int], List[int]]], you can produce it very easily from the previous output:
>>> [(dict((p,)), l) for p, l in idxs.items()]
[({'a': 3}, [0, 1]),
({'d': 4}, [1]),
({'c': 1}, [1, 8]),
({'d': 8}, [2, 4]),
({'c': 0}, [2]),
({'b': 9}, [2]),
({'c': 3}, [3]),
({'a': 9}, [3]),
({'a': 5}, [4]),
({'d': 5}, [5, 8]),
({'b': 5}, [5]),
({'a': 0}, [5]),
({'b': 7}, [6, 7]),
({'c': 7}, [6]),
({'d': 6}, [7]),
({'a': 6}, [7]),
({'a': 4}, [8]),
({'b': 2}, [8]),
({'d': 7}, [9])]
Turn the dictionaries into tuples so you can use them as keys in a dictionary. Then iterate over the list, adding the indexes to this dictionary.
locations_dict = {}
for i, d in enumerate(l):
dtuple = tuple(d.items())
locations_dict.setdefault(dtuple, []).append(i)
locations = [(dict(key), value) for key, value in locations_dict.items()]
from collections import defaultdict
indices = defaultdict(list)
for idx, val in enumerate(l):
indices[tuple(*val.items())].append(idx)
print(indices)
# output
defaultdict(list, {('a', 25): [0, 1], ('b', 30): [2, 4], ('c', 200): [3]})
Another way of doing it:
import ast
l = [{'a':25}, {'a':25}, {'b':30}, {'c':200}, {'b':30}]
n_dict = {}
for a, b in enumerate(l):
n_dict[str(b)] = n_dict.get(str(b), []) + [a]
print(list(zip( [ast.literal_eval(i) for i in n_dict.keys()], n_dict.values() )))
great idea with the dicts/defaultdicts, this also seems to work:
l = [{'a':25}, {'a':25}, {'b':30}, {'c':200}, {'b':30}, {'a': 25}]
sorted_values = sorted(enumerate(l), key=lambda x: str(x[1]))
grouped = itertools.groupby(sorted_values, lambda x: x[1])
grouped_indices = [(k, [x[0] for x in g]) for k, g in grouped]
print(grouped_indices)
the idea is that once an array is sorted (keeping the original indices as additional details) itertools/linux groupby is preaty similar to sql/pandas groupby
I understand that are inertion sorted. I am trying to make a new dictionary that sorts alphabetically on the 'Key' and then sorts the values on the last element in the tuple.
Dictionary Currently:
D1 = {'Lakers': [('James','PG',23,2), ('Davis', 'PF', 3, 3), ('Johnson', 'PG', 33,
1)], 'Pistons': [('Billips', 'PG', 1, 1 ), ('Wallace', 'C', 3, 3)], 'Hawks':
[('Young', 'PG', 11, 1), ('Collins', 'PF', 3, 2)] }
Dictionary I want:
New_D1 = { 'Hawks':[('Collins', 'PF', 3, 2),('Young', 'PG', 11, 1)], 'Lakers': [('Davis', 'PF', 3, 3),('James','PG',23,2), ('Johnson', 'PG', 33, 1)], 'Pistons': [('Wallace', 'C', 3, 3),('Billips', 'PG', 1, 1 ) ] }
My current Code to Sort is:
New_D1 = dict(sorted(D1.items()))
Which creates a new dictionary (New_D1) and only sorts the Keys. I now need to sort the values in the last element of the list of tuples.
You can do this as a comprehension on top of the sort you're already doing:
>>> {k: sorted(v, key=lambda t: -t[-1]) for k, v in sorted(D1.items())}
{'Hawks': [('Collins', 'PF', 3, 2), ('Young', 'PG', 11, 1)], 'Lakers': [('Davis', 'PF', 3, 3), ('James', 'PG', 23, 2), ('Johnson', 'PG', 33, 1)], 'Pistons': [('Wallace', 'C', 3, 3), ('Billips', 'PG', 1, 1)]}
You need to build a new dict, with insertion by sorting the key, and add the values also sorted
result ={}
for key, val in sorted(D1.items()):
result[key] = sorted(val, key=lambda x: x[-1], reverse=True)
You can inline the modification, and not use a tierce dict, with dict-comprehension
D1 = {key: sorted(val, key=lambda x: x[-1], reverse=True) for key, val in sorted(D1.items())}
You can use itemgetter
>>> from operator import itemgetter
>>> {k:sorted(v, key=itemgetter(3)) for k,v in New_D1.items()}
{'Hawks': [('Young', 'PG', 11, 1), ('Collins', 'PF', 3, 2)],
'Lakers': [('Johnson', 'PG', 33, 1), ('James', 'PG', 23, 2), ('Davis', 'PF', 3, 3)],
'Pistons': [('Billips', 'PG', 1, 1), ('Wallace', 'C', 3, 3)]}
{k: sorted(v, key=lambda x: x[:-1]) for k,v in sorted(D1.items(), key=lambda x: x[0])}
It's real simple, and you don't even need the lambda function proposed above:
{k: sorted(v) for k,v in D1.items()}
This produces the result you're looking for:
{'Lakers': [('Davis', 'PF', 3, 3),
('James', 'PG', 23, 2),
('Johnson', 'PG', 33, 1)],
'Pistons': [('Billips', 'PG', 1, 1), ('Wallace', 'C', 3, 3)],
'Hawks': [('Collins', 'PF', 3, 2), ('Young', 'PG', 11, 1)]}
I’m trying to convert a list of tuples to a dictionary with the index of the list as its key.
m = [(1, 'Sports', 222),
(2, 'Tools', 11),
(3, 'Clothing', 23)]
So far, I’ve tried using:
dict((i:{a,b,c}) for a,b,c in enumerate(m))
but this is not working.
My expected output is:
{0: [1, 'Sports', 222],
1: [2, 'Tools', 11],
2: [3, 'Clothing', 23]}
Use the following dictionary comprehension:
>>> {i:list(t) for i, t in enumerate(m)}
{0: [1, 'Sports', 222], 1: [2, 'Tools', 11], 2: [3, 'Clothing', 23]}
It'll work
tuple_list = [(1, 'Sports', 222), (2, 'Tools', 11), (3, 'Clothing', 23)]
output_dict = {}
for index, data in enumerate(tuple_list):
output_dict[index] = list(data)
print(output_dict)
This is my dictionary :
d = {'jan': 50, 'feb': 30, 'march': 60, 'april': 50, 'may': 50, 'june': 60, 'july': 20}
I am expecting output like this :
d = {'jan': 50, 'april': 50, 'may': 50, 'march': 60, 'june': 60, 'feb': 30, 'july': 20}
When I run this program I am getting different output than expected :
d = {'jan': 50, 'feb': 30, 'march': 60, 'april': 50, 'may': 50, 'june': 60, 'july': 20}
sortlist = sorted(d, key=d.get)
print(sortlist)
You can start by counting the amount of times each value appears with collections.Counter:
from collections import Counter
c = Counter(d.values())
# Counter({20: 1, 30: 1, 50: 3, 60: 2})
And now sort the dictionary looking up how many times each value appears using a key in sorted:
sorted(d.items(), key=lambda x: c[x[1]], reverse=True)
[('jan', 50), ('april', 50), ('may', 50), ('march', 60), ('june', 60),
('feb', 30), ('july', 20)]
Note however that if you obtain a dictionary from the result, the order will not be mantained, as dictionaries have no order.
So one thing you can so is use collections.OrderedDict to keep the order, simply call OrderedDict(res) on the resulting list of tuples.
d={'january': 500, 'feb':600, 'march':300,'april':500,'may':500,'june':600,'july':200}
from collections import defaultdict
from collections import OrderedDict
count_dict = defaultdict(int)
for key, value in d.items():
count_dict[value] += 1
First, we count occurences of each value. Counter can be used instead of defaultdict. Then sort them according to count_dict lookup table we just created.
sorted_dict = OrderedDict(sorted(d.items(), key=lambda item: count_dict[item[1]], reverse=True))
print(sorted_dict)
>>> OrderedDict([('january', 500), ('april', 500), ('may', 500), ('feb', 600), ('june', 600), ('march', 300), ('july', 200)])
Update : You can create count_dict with Counter like:
from collections import Counter
count_dict = Counter(d.values())
I'm trying to use a for loop to generate random values for item prices, by changing the value of the item prices in a pre-defined dictionary.
The new values of this pre-defined dictionary are then added to the end of another pre-defined dictionary so a history of prices can be stored.
here is my code:
tradable_good_prices= {'iron' : 0, 'gold' : 0, 'lead' : 0, 'ruby' : 0 'emerald' : 0, 'steel' : 0, 'diamond' : 0}
item_list = tradable_good_prices.keys()
item_price_history = {}
def Random_economy(generations):
for generation_number in range(0, generations):
for list_number in range(0, len(item_list)):
tradable_good_prices[item_list[list_number]] = np.random.random_integers(100,1000)
print(tradable_good_prices)
item_price_history[generation_number] = tradable_good_prices
print(item_price_history)
Random_economy(2)
the code takes in generations as an argument for the number of for loop iterations. And using a value of 2 for generations this output is produced on the console:
{'steel': 821, 'diamond': 477, 'lead': 325, 'gold': 914, 'iron': 542, 'emerald': 360, 'ruby': 705}
{0: {'steel': 821, 'diamond': 477, 'lead': 325, 'gold': 914, 'iron': 542, 'emerald': 360, 'ruby': 705}}
{'steel': 751, 'diamond': 158, 'lead': 322, 'gold': 662, 'iron': 180, 'emerald': 846, 'ruby': 570}
{0: {'steel': 751, 'diamond': 158, 'lead': 322, 'gold': 662, 'iron': 180, 'emerald': 846, 'ruby': 570}, 1: {'steel': 751, 'diamond': 158, 'lead': 322, 'gold': 662, 'iron': 180, 'emerald': 846, 'ruby': 570}}
As can be seen the previous values are being overwritten, I'm guessing theres quite a simple explanation for this like "the dictionary storing the different generation values is referencing the first one for its values" but I cannot find help on this matter anywhere.
So could someone please explain to me what I'm doing wrong.
The keys in a dictionary are unique. If a key exists in a dictionary, d[key] = other_value just changes the value for that key, it does NOT create another item.
>>> d = {'a':1, 'b':'foo'}
>>> d['b'] = 'six'
>>> d
{'b': 'six', 'a': 1}
>>> d.update([('a','bar')])
>>> d
{'b': 'six', 'a': 'bar'}
>>>
If you have data that you want to place in a dictionary and the data contains keys with multiple values, you could put the values into a list for each key. collections.defaultdict makes this easy.
>>> a
[('a', 0), ('b', 1), ('c', 2), ('d', 3), ('e', 4), ('f', 5), ('a', 100), ('c', 99), ('d', 98), ('f', 97)]
>>> import collections
>>> d = collections.defaultdict(list)
>>> for key, value in a:
d[key].append(value)
>>> d
defaultdict(<class 'list'>, {'b': [1], 'a': [0, 100], 'e': [4], 'f': [5, 97], 'd': [3, 98], 'c': [2, 99]})
>>>
For your problem, start with the initial values in a list then add to them.
import random
d = {'a':[0], 'b':[0], 'c':[0]}
for _ in xrange(4):
for key in d:
d[key].append(random.randint(1, 100))
for item in d.items():
print item
>>>
('a', [0, 92, 45, 52, 32])
('c', [0, 51, 85, 72, 4])
('b', [0, 47, 7, 74, 59])
>>>
How to iterate over a dictionary.