I need to delete a k/v pair from a dictionary in a loop. After getting RuntimeError: dictionary changed size during iteration I pickled the dictionary after deleting the k/v and in one of the outer loops I try to reopen the newly pickled/updated dictionary. However, as many of you will probably know-I get the same error-I think when it reaches the top of the loop. I do not use my dictionary in the outermost loop.
So my question is-does anyone know how to get around this problem? I want to delete a k/V pair from a dictionary and use that resized dictionary on the next iteration of the loop.
to focus the problem and use the solution from Cygil
list=[27,29,23,30,3,5,40]
testDict={}
for x in range(25):
tempDict={}
tempDict['xsquared']=x*x
tempDict['xinverse']=1.0/(x+1.0)
testDict[(x,x+1)]=tempDict
for item in list:
print 'the Dictionary now has',len(testDict.keys()), ' keys'
for key in testDict.keys():
if key[0]==item:
del testDict[key]
I am doing this because I have to have some research assistants compare some observations from two data sets that could not be matched because of name variants. The idea is to throw up a name from one data set (say set A) and then based on a key match find all the names attached to that key in the other dataset (set B). One a match has been identified I don't want to show the value from B again to speed things up for them. Because there are 6,000 observations I also don't want them to have to start at the beginning of A each time they get back to work. However, I can fix that by letting them chose to enter the last key from A they worked with. But I really need to reduce B once the match has been identified
Without code, I'm assuming you're writing something like:
for key in dict:
if check_condition(dict[key]):
del dict[key]
If so, you can write
for key in list(dict.keys()):
if key in dict and check_condition(dict[key]):
del dict[key]
list(dict.keys()) returns a copy of the keys, not a view, which makes it possible to delete from the dictionary (you are iterating through a copy of the keys, not the keys in the dictionary itself, in this case.)
Delete all keys whose value is > 15:
for k in mydict.keys(): # makes a list of the keys and iterate
# over the list, not over the dict.
if mydict[k] > 15:
del mydict[k]
Change:
for ansSeries in notmatched:
To:
for ansSeries in notmatched.copy():
Related
I have following code and want now to add all items of "Produkt-Name" to a Dictionary
for col_number, element in enumerate(headings):
for row in ws.iter_rows():
if row[col_number].value is None:
continue
else:
if element == "Produkt-Name":
test = {"productname": row[col_number].value}
The Problem is, I only get the last item of it at the dictionary. I also tested the build in update function but got the last index too.
Every time your conditions are met (the two if statements) you create a new dictionary called "test", the proper syntax to add elements to a dict is :
my_dict[new_key] = value
if new_key already exists, then you will overwrite the old value with the new one, without creating a new key/value pair.
Hope this helps.
Also, as others already pointed out, please produce a minimal reproducible example, we at least need the structure of "headings" and what you would expect as an output.
if you want to have all items under the key 'productname' you can use:
test.setdefault("productname", []).append(row[col_number].value)
but if you want to have your values under different keys you need to set different key names.
Edit: for example: test[key1] = value1, test[key2] = value2, ...
So I have a dictionary names "ngrams_count". I want to find all keys in this dictionary that are in a list called "words_to_find". I would also like to return the values associated with those keys.
So far, this is what I'm working with
ideasrep = [key for key in words_to_find if key in ngrams_count]
That returns only the keys that are found in the word list.
I'm also looking for a way to return only the key/values pairs for which the value is greater than one. I've tried a similar technique as this:
[(key,values) for key, values in ngrams_count.items() if values > 1]
However, this only seems to work if I stay within the dictionary and I'm running out of ideas... Ideally, I'd like a way to do these two things simultaneously.
Your first version is almost right, you just need to add ngrams_count[key] to the result.
ideasrep = [(key, ngrams_count[key]) for key in words_to_find if key in ngrams_count]
Or you can use the second version, but change the condition to check if the key is in words_to_find.
[(key,values) for key, values in ngrams_count.items() if key in words_to_find]
If words_to_find is big, you should convert it to a set before the list comprehension to make the second version more efficient.
I have this dictionary that has tuples as keys. All these tuples got two values, I'll use letters as values to keep things simple, e.g. the tuple (a, b).
The order of the two values doesn't matter, this means that (a, b) is essentially the same as (b, a) (or a sorta duplicate). So I tried to write something that would remove all of these redundant key, value pairs, only it doesn't work and I'm seriously stuck with it. I'm sure that it's just something simple I'm overlooking, regardless I can't figure it out.
I thought this would work:
def undupe_overlaps(overlaps):
dupes = []
for key, item in overlaps.items():
if (key[1], key[0]) in overlaps:
dupes.append((key[1], key[0]))
for item in dupes:
overlaps.pop(item)
return overlaps
overlaps is the dictionary and I use the list dupes cause you can't delete things from a dict and loop over it at the same time. Any help or tips would be appreciated :)
Your if statement is wrong. It should be:
if (key[1], key[0]) not in dupes:
dupes.append(key)
Basically, you are asking that the current key, with element inverted is not already present inside the dupes list.
Your piece of code does not work because you are looking at overlaps, and inserting the current key if the inverted one is present. That way, the "single" keys, i.e. those that do not have their counterpart, are never inserted in dupers.
You can convert the keys into a list separately from the dict and then modify the dict as you iterate through the keys.
def undupe_overlaps(overlaps):
dupes = set()
for key_tuple in list(overlaps.keys()):
if key_tuple in dupes or (key_tuple[1], key_tuple[0]) in dupes:
overlaps.pop(key_tuple)
dupes.add(key_tuple)
return overlaps
My problem is understanding why these certain lines of code do what they do. Basically why it works logically. I am using PyCharm python 3 I think.
house_Number = {
"Luca": 1, "David": 2, "Alex": 3, "Kaden": 4, "Kian": 5
}
for item in house_Number:
print(house_Number[item]) # Why does this print the values tied with the key?
print(item) # Why does this print the key?
This is my first question so sorry I don't know how to format the code to make it look nice. My question is why when you use the for loop to print the dictionary key or value the syntax to print the key is to print every item? And what does it even mean to print(house_Number[item]).
They both work to print key or value but I really want to know a logical answer as to why it works this way. Thanks :D
I'm not working on any projects just starting to learn off of codeacademey.
In Python, iteration over a dictionary (for item in dict) is defined as iteration over that dictionary's keys. This is simply how the language was designed -- other languages and collection classes do it differently, iterating, for example, over key-value tuples, templated Pair<X,Y> objects, or what have you.
house_Number[item] accesses the value in house_Number referenced by the key item. [...] is the syntax for indexing in Python (and most other languages); an_array[2] gives the third element of an_array and house_Number[item] gives the value corresponding to the key item in the dictionary house_Number.
Just a side note: Python naming conventions would dictate house_number, not house_Number. Capital letters are generally only used in CamelCasedClassNames and CONSTANTS.
In python values inside a dictionary object are accessed using dictionay_name['KEY']
In your case you are iterating over the keys of dictionary
Hope this helps
for item in dic:
print(item) # key
print(dic[item]) # value
Dictionaries are basically containers containing some items (keys) which are stored by hashing method. These keys just map to the values (dic[key]).
Like in set, if you traverse using for loop, you get the keys from it (in random order since they are hashed). Similarly, dictionaries are just sets with a value associated with it. it makes more sense to iterate the keys as in sets (too in random order).
Read more about dicionaries here https://docs.python.org/3/tutorial/datastructures.html#dictionaries and hopefully that will answer your question. Specifically, look at the .items() method of the dictionary object.
When you type for item in house_Number, you don’t specify whether item is the key or value of house_Number. Then python just thinks that you meant the key of house_Number.
So when you do the function print(house_Number[item]), you’re printing the value because your taking the key and finding the value. In other words, you taking each key once, and finding their values, which are 1, 2, 3, 4, 5, 6
The print(item) is just to print the item, which are the keys, "Luca", "David", "Alex", "Kaden", "Kian"
Because the print(house_Number[item]) and print(item) alternating, you get the keys and values alternating, each on a new line.
Suppose I have a dictionary:
dictionary1 = {'test':'output','test2':'output2'}
How would I be able to print the key, test, on the screen?
I only want one of the keys at a time, not all of them.
By the way, not literally, by doing print('test'), I mean how do you print the key of any dictionary?
Like is there something like this:
#pseudocode
x = dictionary1.keys()[0]
>>> print(x)
'test'
I do not want to sort the dictionary that I'm actually using in my program.
A dictionary may have any number of keys, 0+. To print them all (if any) in sorted order, you could
for key in sorted(dictionary1):
print(key)
If you don't care about the order (i.e you're fine with a random-looking order), remove the sorted call.
If you want to be selective (e.g only print keys that are sequences of length 4, so that in your example test would be printed but test2 wouldn't):
for key in sorted(dictionary1):
try:
if len(key) == 4:
print(key)
except TypeError:
pass
If you want to print only one such key, add a break after the print.
There are at least 347 other things you could mean by your extremely vague question, but I tried to field the ones that seem most likely... if that's not enough for you, edit your question to make it much more precise!-)
Added: the edit only said the OP wants to print only one key and do no sorting, so it remains a mystery how that one key is to be picked (I suspect there's a misunderstanding -- as if dict keys had a specific order, which of course in Python they don't, and the OP wants "the first one", which just can't be pinned down -- OrderedDict is a very different [and alas inevitably slower] beast, but dicts what the OP's showing).
So if the goal is to print "any one key, no matter which one" (and it is known that thedict is not empty):
print(next(iter(thedict)))
is the simplest, most direct way -- a dict is iterable, yielding its keys in arbitrary order; iter returns an iterator on its iterable argument; and next returns the first (first in arbitrary order means an arbitrary one of course) item of its iterator argument.
If it's possible for thedict to be empty, and nothing must be printed in that case, just add a guard:
if thedict: print(next(iter(thedict)))
This will print nothing for an empty dictionary, the only key for a dictionary with length 1, an arbitrary key for a dictionary with length greater than 1.
If you're trying to find a key associated with a specific value you can do
keys = [key for key in d if d[key] == value]
print(keys)