How to loop inside a dictionary which has values as arrays - python

I want to loop inside a dictionary that has arrays as values and get each element of the array. How do I do that? I tried this but it didn't work:
array = {'Secretary' : [0,1,2,3,4] , 'Admin' : [0,2,3,4,1]}
for key,value in array.items():
for v in value:
print(v[count])
count = count + 1

It appears you are trying to use count as an indexer. But this isn't necessary are you iterating over the elements of each list for each dictionary value. In addition, for iterating over values only, you can use the dict.values view. So you can use:
for value in array.values():
for v in value:
print(v)
If you wish to create a list combining all elements in all list values, you can use itertools.chain:
from itertools import chain
array = {'Secretary' : [0,1,2,3,4] , 'Admin' : [0,2,3,4,1]}
res = list(chain.from_iterable(array.values()))
[0, 1, 2, 3, 4, 0, 2, 3, 4, 1]

You can get a complete list of all the values by pulling each item from within d.values()
d = {'Secretary' : [0,1,2,3,4] , 'Admin' : [0,2,3,4,1]}
l = [i for v in d.values() for i in v]
# [0, 1, 2, 3, 4, 0, 2, 3, 4, 1]
Expanded
l = []
for v in d.values():
for i in v:
l.append(i)

You have the basic idea right. There are a few ways you can do this. I recommend reading py docs for the classes dict, enum, and list; create solutions using all of them; and to document your code with explanations of what's happening for each of them. It sounds kind of 'douchey', and I apologize for that, but it's important to understand how to read/use this information.
As to fixing the errors in your code snippet:
a_dict={'Secretary' : [0,1,2,3,4] , 'Admin' : [0,2,3,4,1]} #because this is a dict OF arrays.
for key,value in a_dict.items(): #what this does. (hint, use the word tuple)
count = 0 #initialize the value of count to 0
while count < len(value):
print(value[count])
count =count+1
count = 0 #reset the value of count to 0
Another way to do this:
a_dict={'Secretary' : [0,1,2,3,4] , 'Admin' : [0,2,3,4,1]} #because this is a dict OF arrays.
for values in a_dict.values(): #what this does. (hint, method from dict class)
for value in values:
print(value)
And another:
a_dict={'Secretary' : [0,1,2,3,4] , 'Admin' : [0,2,3,4,1]} #because this is a dict OF arrays.
for values in a_dict.values(): #what this does. (hint, method from dict class)
for idx in range(len(values)): #code comments are very useful
print(values[idx])
One more just for because:
a_dict={'Secretary' : [0,1,2,3,4] , 'Admin' : [0,2,3,4,1]} #because this is a dict OF arrays.
for key in a_dict.keys(): #what this does. (hint, method from dict class)
vals = a_dict.get(key)
for idx,value in enumerate(vals): #code comments are very useful
print(key + ':', value, '\n')
If you're struggling to understand the docs, then that's what you should ask for help on. Just be specific with what you're not understanding, and keep at it. You're not always going to feel like you need a manual on how to understand the manual. This is just python however. It has nothing to do with Django.

Related

How to check if tuple key contains an element in dictionary

I am looking for an operation that could do something similar to this:
dict[ ( tuple[0] , _ ) ]
The dictionary contains tuples as keys.
How do I check if the dictionary contains a value where the tuple key has a specific value as the first part and any value as the second part?
Try this,
#Dictionary with tuples as keys
dict_with_tup = dict([((1,2),3), ((1,4),2), ((2,5),7)])
#value that you wanna find (just the first value of the tuple)
x = 1
#filtered dict based on that value
{k:v for k,v in dict_with_tup.items() if k[0]==x}
{(1, 2): 3, (1, 4): 2}
for a dictionary d
x = # value of interest
for key in d.keys():
if key[0] == x:
#do stuff
but as khelwood noted in the comments, it's not a very efficient way of doing things

Removing duplicates in values of dictionary in python

Sorry the topic's title is vague, I find it hard to explain.
I have a dictionary in which each value is a list of items. I wish to remove the duplicated items, so that each item will appear minimum times (preferable once) in the lists.
Consider the dictionary:
example_dictionary = {"weapon1":[1,2,3],"weapon2":[2,3],"weapon3":[2,3]}
'weapon2' and 'weapon3' have the same values, so it should result in:
result_dictionary = {"weapon1":[1],"weapon2":[3],"weapon3":[2]}
since I don't mind the order, it can also result in:
result_dictionary = {"weapon1":[1],"weapon2":[2],"weapon3":[3]}
But when "there's no choice" it should leave the value. Consider this new dictionary:
example_dictionary = {"weapon1":[1,2,3],"weapon2":[2,3],"weapon3":[2,3],"weapon4":[3]}
now, since it cannot assign either '2' or '3' only once without leaving a key empty, a possible output would be:
result_dictionary = {"weapon1":[1],"weapon2":[3],"weapon3":[2],"weapon4":[3]}
I can relax the problem to only the first part and manage, though I prefer a solution to the two parts together
#!/usr/bin/env python3
example_dictionary = {"weapon1":[1,2,3],"weapon2":[2,3],"weapon3":[2,3]}
result = {}
used_values = []
def extract_semi_unique_value(my_list):
for val in my_list:
if val not in used_values:
used_values.append(val)
return val
return my_list[0]
for key, value in example_dictionary.items():
semi_unique_value = extract_semi_unique_value(value)
result[key] = [semi_unique_value]
print(result)
This is probably not the most efficient solution possible. Because it involves iteration over all possible combinations, then it'll run quite slow for large targets.
It makes use of itertools.product() to get all possible combinations. Then in it, tries to find the combination with the most unique numbers (by testing the length of a set).
from itertools import product
def dedup(weapons):
# get the keys and values ordered so we can join them back
# up again at the end
keys, vals = zip(*weapons.items())
# because sets remove all duplicates, whichever combo has
# the longest set is the most unique
best = max(product(*vals), key=lambda combo: len(set(combo)))
# combine the keys and whatever we found was the best combo
return {k: [v] for k, v in zip(keys, best)}
From the examples:
dedup({"weapon1":[1,2,3],"weapon2":[2,3],"weapon3":[2,3]})
#: {'weapon1': 1, 'weapon2': 2, 'weapon3': 3}
dedup({"weapon1":[1,2,3],"weapon2":[2,3],"weapon3":[2,3],"weapon4":[3]})
#: {'weapon1': 1, 'weapon2': 2, 'weapon3': 2, 'weapon4': 3}
this could help
import itertools
res = {'weapon1': [1, 2, 3], 'weapon2': [2, 3], 'weapon3': [2, 3]}
r = [[x] for x in list(set(list(itertools.chain.from_iterable(res.values()))))]
r2 = [x for x in res.keys()]
r3 = list(itertools.product(r2,r))
r4 = dict([r3[x] for x in range(0,len(r3)) if not x%4])

How to find length of dictionary values

I am pretty new to all of this so this might be a noobie question.. but I am looking to find length of dictionary values... but I do not know how this can be done.
So for example,
d = {'key':['hello', 'brave', 'morning', 'sunset', 'metaphysics']}
I was wondering is there a way I can find the len or number of items of the dictionary value.
Thanks
Sure. In this case, you'd just do:
length_key = len(d['key']) # length of the list stored at `'key'` ...
It's hard to say why you actually want this, but, perhaps it would be useful to create another dict that maps the keys to the length of values:
length_dict = {key: len(value) for key, value in d.items()}
length_key = length_dict['key'] # length of the list stored at `'key'` ...
Lets do some experimentation, to see how we could get/interpret the length of different dict/array values in a dict.
create our test dict, see list and dict comprehensions:
>>> my_dict = {x:[i for i in range(x)] for x in range(4)}
>>> my_dict
{0: [], 1: [0], 2: [0, 1], 3: [0, 1, 2]}
Get the length of the value of a specific key:
>>> my_dict[3]
[0, 1, 2]
>>> len(my_dict[3])
3
Get a dict of the lengths of the values of each key:
>>> key_to_value_lengths = {k:len(v) for k, v in my_dict.items()}
{0: 0, 1: 1, 2: 2, 3: 3}
>>> key_to_value_lengths[2]
2
Get the sum of the lengths of all values in the dict:
>>> [len(x) for x in my_dict.values()]
[0, 1, 2, 3]
>>> sum([len(x) for x in my_dict.values()])
6
To find all of the lengths of the values in a dictionary you can do this:
lengths = [len(v) for v in d.values()]
A common use case I have is a dictionary of numpy arrays or lists where I know they're all the same length, and I just need to know one of them (e.g. I'm plotting timeseries data and each timeseries has the same number of timesteps). I often use this:
length = len(next(iter(d.values())))
Let dictionary be :
dict={'key':['value1','value2']}
If you know the key :
print(len(dict[key]))
else :
val=[len(i) for i in dict.values()]
print(val[0])
# for printing length of 1st key value or length of values in keys if all keys have same amount of values.
d={1:'a',2:'b'}
sum=0
for i in range(0,len(d),1):
sum=sum+1
i=i+1
print i
OUTPUT=2

Python Iterate Dictionary by Index

I want to iterate through a dictionary in python by index number.
Example :
dict = {'apple':'red','mango':'green','orange':'orange'}
I want to iterate through the dictionary from first to last, so that I can access the dictionary items by their indexes. For example, the 1st item will be apple, and the 2nd item will be mango and value will be green.
Something like this:
for i in range(0,len(dict)):
dict.i
You can iterate over keys and get values by keys:
for key in dict.iterkeys():
print key, dict[key]
You can iterate over keys and corresponding values:
for key, value in dict.iteritems():
print key, value
You can use enumerate if you want indexes (remember that dictionaries don't have an order):
>>> for index, key in enumerate(dict):
... print index, key
...
0 orange
1 mango
2 apple
>>>
There are some very good answers here. I'd like to add the following here as well:
some_dict = {
"foo": "bar",
"lorem": "ipsum"
}
for index, (key, value) in enumerate(some_dict.items()):
print(index, key, value)
results in
0 foo bar
1 lorem ipsum
Appears to work with Python 2.7 and 3.5
I wanted to know (idx, key, value) for a python OrderedDict today (mapping of SKUs to quantities in order of the way they should appear on a receipt). The answers here were all bummers.
In python 3, at least, this way works and and makes sense.
In [1]: from collections import OrderedDict
...: od = OrderedDict()
...: od['a']='spam'
...: od['b']='ham'
...: od['c']='eggs'
...:
...: for i,(k,v) in enumerate(od.items()):
...: print('%d,%s,%s'%(i,k,v))
...:
0,a,spam
1,b,ham
2,c,eggs
Some of the comments are right in saying that these answers do not correspond to the question.
One reason one might want to loop through a dictionary using "indexes" is for example to compute a distance matrix for a set of objects in a dictionary. To put it as an example (going a bit to the basics on the bullet below):
Assuming one have 1000 objects on a dictionary, the distance square
matrix consider all combinations from one object to any other and so
it would have dimensions of 1000x1000 elements. But if the distance
from object 1 to object 2 is the same as from object 2 to object 1,
one need to compute the distance only to less than half of the square
matrix, since the diagonal will have distance 0 and the values are
mirrored above and below the diagonal.
This is why most packages use a condensed distance matrix ( How does condensed distance matrix work? (pdist) )
But consider the case one is implementing the computation of a distance matrix, or any kind of permutation of the sort. In such case you need to skip the results from more than half of the cases. This means that a FOR loop that runs through all the dictionary is just hitting an IF and jumping to the next iteration without performing really any job most of the time. For large datasets this additional "IFs" and loops add up to a relevant amount on the processing time and could be avoided if, at each loop, one starts one "index" further on the dictionary.
Going than to the question, my conclusion right now is that the answer is NO. One has no way to directly access the dictionary values by any index except the key or an iterator.
I understand that most of the answers up to now applies different approaches to perform this task but really don't allow any index manipulation, that would be useful in a case such as exemplified.
The only alternative I see is to use a list or other variable as a sequential index to the dictionary. Here than goes an implementation to exemplify such case:
#!/usr/bin/python3
dishes = {'spam': 4.25, 'eggs': 1.50, 'sausage': 1.75, 'bacon': 2.00}
print("Dictionary: {}\n".format(dishes))
key_list = list(dishes.keys())
number_of_items = len(key_list)
condensed_matrix = [0]*int(round(((number_of_items**2)-number_of_items)/2,0))
c_m_index = 0
for first_index in range(0,number_of_items):
for second_index in range(first_index+1,number_of_items):
condensed_matrix[c_m_index] = dishes[key_list[first_index]] - dishes[key_list[second_index]]
print("{}. {}-{} = {}".format(c_m_index,key_list[first_index],key_list[second_index],condensed_matrix[c_m_index]))
c_m_index+=1
The output is:
Dictionary: {'spam': 4.25, 'eggs': 1.5, 'sausage': 1.75, 'bacon': 2.0}
0. spam-eggs = 2.75
1. spam-sausage = 2.5
2. spam-bacon = 2.25
3. eggs-sausage = -0.25
4. eggs-bacon = -0.5
5. sausage-bacon = -0.25
Its also worth mentioning that are packages such as intertools that allows one to perform similar tasks in a shorter format.
Do this:
for i in dict.keys():
dict[i]
Since you want to iterate in order, you can use sorted:
for k, v in sorted(dict.items()):
print k,v
There are several ways to call the for-loop in python and here what I found so far:
A = [1,2,3,4]
B = {"col1": [1,2,3],"col2":[4,5,6]}
# Forms of for loop in python:
# Forms with a list-form,
for item in A:
print(item)
print("-----------")
for item in B.keys():
print(item)
print("-----------")
for item in B.values():
print(item)
print("-----------")
for item in B.items():
print(item)
print("The value of keys is {} and the value of list of a key is {}".format(item[0],item[1]))
print("-----------")
Results are:
1
2
3
4
-----------
col1
col2
-----------
[1, 2, 3]
[4, 5, 6]
-----------
('col1', [1, 2, 3])
The value of keys is col1 and the value of list of a key is [1, 2, 3]
('col2', [4, 5, 6])
The value of keys is col2 and the value of list of a key is [4, 5, 6]
-----------
When I need to keep the order, I use a list and a companion dict:
color = ['red','green','orange']
fruit = {'apple':0,'mango':1,'orange':2}
color[fruit['apple']]
for i in range(0,len(fruit)): # or len(color)
color[i]
The inconvenience is I don't get easily the fruit from the index. When I need it, I use a tuple:
fruitcolor = [('apple','red'),('mango','green'),('orange','orange')]
index = {'apple':0,'mango':1,'orange':2}
fruitcolor[index['apple']][1]
for i in range(0,len(fruitcolor)):
fruitcolor[i][1]
for f, c in fruitcolor:
c
Your data structures should be designed to fit your algorithm needs, so that it remains clean, readable and elegant.
I can't think of any reason why you would want to do that. If you just need to iterate over the dictionary, you can just do.
for key, elem in testDict.items():
print key, elem
OR
for i in testDict:
print i, testDict[i]

What's the best way to add two elements of an object to a list without repeating them?

Performance, elegancy and readability are the requirements for "the best way"
I have the array of dictionaries:
items = [
{'id1' : 1, 'id2' : 2, 'other' : 'xxx'},
{'id1' : 1, 'id2' : 3, 'other' : 'yyy'},
{'id1' : 2, 'id2' : 4, 'other' : 'zzz'}
]
The result should be: ids = [1,2,3,4] (list of id1 and id2)
Edit:
Something like this:
ids = []
for item in items:
if item.id1 not in ids:
ids.append(item.id1)
if item.id2 not in ids:
ids.append(item.id2)
>>> set(x for y in items for x in y.values())
set([1, 2, 3, 4])
Update for updated question
>>> set(v for y in items for (k,v) in y.items() if k.startswith('id'))
set([1, 2, 3, 4])
This could be done pretty easily by using itertools.chain.from_iterable() to flatten a nested generator expression producing the values of the ids - we presume that all keys are going to be strings, and that starting with "id" specifies an id. We then make a set of those values to remove duplicates:
from itertools import chain
set(chain.from_iterable((value for name, value in item.items()
if name.startswith("id"))
for item in items))
If you really want a list, then you could create one from the set, but in most cases, the set should be fine as-is. Note that the set has no order, so if you want an order you will need to use sorted(), for example.
itertools.chain.from_iterable() is the most efficient and readable way to flatten an iterable.
Your specification isn't clear when it comes to what an id is. If you have a set of keys which define an id, then something like this might be more appropriate as the if clause of the inner generator expression:
if name in {"id1", "id2"}

Categories