How to convert an associative array in python? - python

I am really new to python and I can't find any information about this. I have an associative array item,
item['id'] = 0
item['title'] = 'python'
I want to validate the contents of item but I dont want to use the index name like 'title' but just have a for loop and iterate over all entries in item regardless of their meaning. Something like that
for a in range(0, len(item)):
print (item[a])
Any ideas or suggestions?

In Python, associative arrays are called dictionaries.
A good way to iterate through a dict is to use .iteritems():
for key, value in item.iteritems():
print key, value
If you only need the values, use .itervalues():
for value in item.itervalues():
print value
As you learn more about Python and dictionaries, take note of the difference between .iteritems()/itervalues() (which returns an iterator) and items()/values()(which returns a list (array)).
In Python 3
.iteritems()/.itervalues() have been removed and items()/values()/keys() return iterators on the corresponding sequences.
for key, value in item.items():
print(key)
print(value)

There are three ways to iterate a dictionary:
item = {...}
for key in item: # alternatively item.iterkeys(), or item.keys() in python 3
print key, item[key]
item = {...}
for value in item.itervalues(): # or item.values() in python 3
print value
item = {...}
for key, value in item.iteritems(): # or item.items() in python 3
print key, value

Related

Dict comprehension from split str

I'm trying to make a dict out this str:
a='ALLELEID=677660;CLNDISDB=MedGen:C0162671,OMIM:540000,Orphanet:ORPHA550,SNOMED_CT:39925003;CLNDN=Juvenile_myopathy,_encephalopathy,_lactic_acidosis_AND_stroke;CLNHGVS=NC_012920.1:m.15992A>T;CLNREVSTAT=criteria_provided,_single_submitter;CLNSIG=Likely_benign;CLNVC=single_nucleotide_variant;CLNVCSO=SO:0001483;GENEINFO=MT-TP:4571;ORIGIN=1'
This works:
d={}
for i in a.split(';'):
key, val = i.split('=')
d[key] = val
Why doesn't this work?
d={key: val for key, val in i.split('=') for i in a.split(';')}
You cannot have nested dictionary comprehensions (unlike nested list comprehensions). The following will work:
dict(item.split("=") for item in a.split(';'))
dict() can build a dictionary from a list of 2-element lists or tuples.
Try using:
d={i.split('=')[0]: i.split('=')[1] for i in a.split(';')}
The second loop isn't needed (even if you needed it it would be wrong, you would need to put the second loop after the first loop).
To use list comprehensions here you should use:
{key: val for i in a.split(';'), for key, val in i.split('=')}
But even you changed your code to this, it won't work since this is wrong:
for key, val in i.split('=')
the results of i.split('=') is an 1d array where you can only iterate with one element.
So eventually, you will only need one level of list comprehension:
{i.split('=')[0]: i.split('=')[1] for i in a.split(';')}

confused with python dictionary methods.values() .keys()

why this code isn't working? trying to get returns on items which value==key
L=[0,2,2,1,5,5,6,10]
x=dict(enumerate(L))
y=(filter(x.keys()==x.values(), x.items()))
print(list(y))
The keys() method returns a view of all of the keys.
The values() method returns a view of all of the values.
So, x.keys()==x.values() is asking whether all of the keys equal all of the values, which is of course not true.
Also, filter wants a function. But you're not passing it a function, you're just passing it the result of x.keys()==x.values(), or False. To turn that into a function, you'd need to use def or lambda to create a new function.
The function you want to create is a function that takes an item, and returns true if the key equals the value. Since an item is just a 2-element tuple with the key and value for that item, the function to check that is:
y = filter((lambda item: item[0] == item[1]), x.items())
Or, if that's a bit too confusing, don't try to write it inline; just def it separately:
def key_equals_value(item):
key, value = item
return key == value
y = filter(key_equals_value, x.items())
However, this is pretty clumsy; it's much easier to write it as a comprehension than a filter call:
y = ((key, value) for (key, value) in x.items() if key == value)
As a general rule, whenever you don't already have a function to pass to filter or map, and would have to create one with def or lambda, a comprehension will usually be more readable, because you can just write the expression directly.
And, if you want a list rather than a generator, you can do that with a comprehension just by changing the parens to square brackets:
y = [(key, value) for (key, value) in x.items() if key == value]
And, if you want just the values, not the key-value pairs:
y = [value for (key, value) in x.items() if key == value]
If you find yourself confused by comprehensions, they can always be converted into nested statements, with an append at the bottom. So, that last one is equivalent to:
y = []
for key, value in x.items():
if key == value:
y.append(value)
Also, you don't really need a dict here in the first place; you just want to iterate over the index, value pairs. So:
y = [value for (index, value) in enumerate(L) if index == value]

How to access dictionary elements in a list in python

I'm trying to understand about dictionaries and list in Python.
Assume that I have a list which contains 3 dictionaries
Ex. item_list = [price,stock,quantity]
price, stock and quantity are the dictionaries here. Each dictionary has few key-value pairs like
price = {'toys':25,'clothes':[12,15,20]}
I know to access individual elements, I can use a for loop with the keys specified like:
for item in item_list:
print item['toys']
How do I access the elements without directly mentioning the key in the for loop?
You can iterate over a dictionary just like you can iterate over a list.
for item in item_list:
for key in item:
print item[key]
In a sense, you're still mentioning the keys, but you're not referencing them explicitly by their value.
If you're just interested in the values you can use the values() method:
for item in item_list:
for key in item.values():
print item[key]
My preferred way to iterate over dictionaries though is with items, which returns a tuple of key, value pairs.
for item in item_list:
for key, value in item.items():
print key, value
I would do something like this:
for item in item_list:
for key, value in item.iteritems():
print key, value
Let us say, you have a list like this
prices_list = [{'toys':25,'clothes':[12,15,20]},{'toys':35,'clothes':[12,15,20]}]
And you would like to get the value corresponding to toys, but without specifying the name in the for loop. So, you can use operator.itemgetter like this
from operator import itemgetter
getter = itemgetter("toys")
print [getter(item) for item in prices_list]
# [25, 35]
The same can be used like this
total = 0
for item in prices_list:
total += getter(item)
for d in item_list:
for i in d.values():
print i
You could also call d.items() and get back tuples of (key, value) if you wanted access to both.
Additionally if you don't care about readability you could use this to get a list of all the values accross the dicts in your list.
[x for y in (i.values() for i in item_list) for x in y]
You can also use: [d for i in item_list for d in i.values()] to get the values and flatten them into a list (though yours would still be nested because of clothes' value being a list.
Finally you can merge the dictionaries into one if they have distinct keys:
joint_mapping = dict([d for i in item_list for d in i.items()])
or if they don't have unique values you can use the below code to produce a dict of lists of values. :
for k, v in [d for i in item_list for d in i.items()]:
new_d[k] = new_d.get(k, [])+[v]
You mentioned :
#Eenvincible - I would be inputting those values to other variable.
Print is just an example I gave. So would not want to hardcode the key.
I think you can do your trick using for loop as mentioned in other answers.
for item in item_list:
for key in item:
print item[key]
tempvariable = item[key]
.... do something here.
If you want to assign each value to a seperate variable, you should:
- First, assign that variables to any insignificant value EX: **None** or *""*
- Then, dynamically use the for loop to reassign each variable to new value using if condition or thier index.
EX:
price_toys , price_clothes , stock_toys , stock_clothes = None , None , None , None
for item in item_list:
for key in item:
tempvariable = item[key]
# condition to choose which varible will be set to the current value.
if item == "price" and key == "toys":
price_toys = tempvariable
# and so on

How to fetch the key/value pair of a dictionary only containing one item?

Let's say I have dict. I don't know the key/value inside. How do I get this key and the value without doing a for loop (there is only one item in the dict).
You might wonder why I am using a dictionary in that case. I have dictionaries all over my API and I don't want the user to be lost. It's only a matter of consistency. Otherwise, I would have used a list and indexes.
Use the proper data type for the job. Your goal should be to have workable code, not that you use the same data type all over the place.
If your dictionary only contains one key and one value, you can get either with indexing:
key = list(d)[0]
value = list(d.values())[0]
or to get both:
key, value = list(d.items())[0]
The list calls are needed because in Python 3, .keys(), .values() and .items() return dict views, not lists.
Another option is to use sequence unpacking:
key, = d
value, = d.values()
or for both at the same time:
(key, value), = d.items()
Just get the first item in the dictionary using an iterator
>>> d = {"foo":"bar"}
>>> k, v = next(iter(d.items()))
>>> k
'foo'
>>> v
'bar'
You can do this:
>>> d={1:'one'}
>>> k=list(d)[0]
>>> v=d[k]
Works in Python 2 or 3
d.popitem() will give you a key,value tuple.

How to solve dictionary changed size during iteration error?

I want pop out all the large values and its keys in a dictionary, and keep the smallest. Here is the part of my program
for key,value in dictionary.items():
for key1, value1 in dictionary.items():
if key1!= key and value > value1:
dictionary.pop(key)
print (dictionary)
Which results in
RuntimeError: dictionary changed size during iteration
How can I avoid this error?
In Python3, Try
for key in list(dict.keys()):
if condition:
matched
del dict[key]
1 more thing should be careful when looping a dict to update its key:
Code1:
keyPrefix = ‘keyA’
for key, value in Dict.items():
newkey = ‘/’.join([keyPrefix, key])
Dict[newkey] = Dict.pop(key)
Code2:
keyPrefix = ‘keyA’
for key, value in Dict.keys():
newkey = ‘/’.join([keyPrefix, key])
Dict[newkey] = Dict.pop(key)
Result of code1/code2 is:
{‘keyA/keyA/keyB’ : ”, ‘keyA/keyA/keyA’: ”}
My way to resolve this unexpected result:
Dict = {‘/’.join([keyPrefix, key]): value for key, value in Dict.items()}
Link: https://blog.gainskills.top/2016/07/21/loop-a-dict-to-update-key/
Alternative solutions
If you're looking for the smallest value in the dictionary you can do this:
min(dictionary.values())
If you cannot use min, you can use sorted:
sorted(dictionary.values())[0]
Why do I get this error?
On a side note, the reason you're experiencing an Runtime Error is that in the inner loop you modify the iterator your outer loop is based upon. When you pop an entry that is yet to be reached by the outer loop and the outer iterator reaches it, it tries to access a removed element, thus causing the error.
If you try to execute your code on Python 2.7 (instead of 3.x) you'll get, in fact, a Key Error.
What can I do to avoid the error?
If you want to modify an iterable inside a loop based on its iterator you should use a deep copy of it.
You can use copy.deepcopy to make a copy of the original dict, loop over the copy while change the original one.
from copy import deepcopy
d=dict()
for i in range(5):
d[i]=str(i)
k=deepcopy(d)
d[2]="22"
print(k[2])
#The result will be 2.
Your problem is iterate over something that you are changing.
Record the key during the loop and then do dictionary.pop(key) when loop is done. Like this:
for key,value in dictionary.items():
for key1, value1 in dictionary.items():
if key1!= key and value > value1:
storedvalue = key
dictionary.pop(key)
Here is one way to solve it:
From the dictionary, get a list of keys, sorted by value
Since the first key in this list has the smallest value, you can do what you want with it.
Here is a sample:
# A list of grades, not in any order
grades = dict(John=95,Amanda=89,Jake=91,Betty=97)
# students is a list of students, sorted from lowest to highest grade
students = sorted(grades, key=lambda k: grades[k])
print 'Grades from lowest to highest:'
for student in students:
print '{0} {1}'.format(grades[student], student)
lowest_student = students[0]
highest_student = students[-1]
print 'Lowest grade of {0} belongs to {1}'.format(grades[lowest_student], lowest_student)
print 'Highest grade of {0} belongs to {1}'.format(grades[highest_student], highest_student)
The secret sauce here is in the sorted() function: instead of sorting by keys, we sorted by values.
If you want to just keep the key with the smallest value, I would do it by first finding that item and then creating a new dictionary containing only it. If your dictionary was d, something like this would do that in one line:
d = dict((min(d.items(), key=lambda item: item[1]),))
This will not only avoid any issues about updating the dictionary while iterating it, it is probably faster than removing all the other elements.
If you must do the modifications in-place for some reason, the following would work because it makes a copy of all the keys before modifying the dictionary:
key_to_keep = min(d.items(), key=lambda item: item[1])[0]
for key in list(d):
if key != key_to_keep:
d.pop(key)
As I read your loop right now, you're looking to keep only the single smallest element, but without using min. So do the opposite of what your code does now, check if value1 < minValueSoFar, if so, keep key1 as minKeySoFar. Then at the end of the loop (as Zayatzz suggested), do a dictionary.pop(minKeySoFar)
As an aside, I note that the key1!=key test is irrelevant and computationally inefficient assuming a reasonably long list.
minValueSoFar = 9999999; # or whatever
for key,value in dictionary.items():
if value < minValueSoFar:
minValueSoFar = value
minKeySoFar = key
dictionary.pop(minKeySoFar) # or whatever else you want to do with the result
An alternative solution to dictionary changed size during iteration:
for key,value in list(dictionary.items()):
for key1, value1 in list(dictionary.items()):
if key1!= key and value > value1:
dictionary.pop(key)
print (dictionary)
Better use it with caution! when using this type of code, because list(dictionary.items()) calculated when the complier enters first time to loop. Therefore any change made on dictionary won't affect process inside the current loop.
You could create a list with the vaules you want to delete and than run a second for loop:
for entry in (listofkeystopop):
dictionary.pop(entry)

Categories

Resources