Python delete dictionary items with same values - python-3.x

How would I remove dictionary items that have different keys but identical values? I am sure there a better way than my novice algorithm...?
Example: (abends with error "dictionary changed size during iteration")
The goal of this example is to remove either 'car_id' or 'truck_id' from dict.
key_fields_obj = {}
key_fields_obj['car_id'] = 'bob'
key_fields_obj['bike_id'] = 'sam'
key_fields_obj['truck_id'] = 'bob' #goal: remove this one, so left with only car_id and bike_id
for item in key_fields_obj:
tst = key_fields_obj[item]
for comp in key_fields_obj:
if item == comp:
continue
cmp = key_fields_obj[comp]
if cmp == tst:
del key_fields_obj[comp]
print(key_fields_obj)

Create a new dict with values as key and key as values, then perform the same again on new dict.
>>> key_fields_obj = {key_fields_obj[key]: key for key in key_fields_obj}
>>> key_fields_obj
{'bob': 'truck_id', 'sam': 'bike_id'}
>>>
>>> key_fields_obj = {key_fields_obj[key]: key for key in key_fields_obj}
>>> key_fields_obj
{'truck_id': 'bob', 'bike_id': 'sam'}

seem_values = set()
for key, value in list(key_fields_obj.items()):
if value in seem_values:
del key_fields_obj[key]
else:
seem_values.add(value)

Related

Find and replace list value in a dictionary python 3

I'm new to python. I'm trying to find and remove duplicate list values from the dictionary below:
dict = {'happy':['sun', 'moon', 'bills' 'chocolate'], 'sad':['fail', 'test', 'bills', 'baloon'], 'random': ['baloon', 'france', 'sun'] }
I want the dictionary dictionary to look like this after removing the duplicates from the list
expectd_dict = {'happy':['sun', 'moon', 'chocolate', 'bills'], 'sad':['fail', 'test','baloon'], 'random': ['france] }
I have looked for solutions on the internet but to no avail. I have tried creating an empty list and dict, iterating through the dictionary key and value, and also iterating through the list values, then adding it the to the empty list if not present, but I don't seem to be getting the desired result.
output_dict = {}
output_list = []
for key, value in d.items():
if key not in output_dict.values():
for i in value:
if i not in output_list:
output_list.append(i)
output_dict[key] = output_list
print(output_dict)
Think you want process lists in the order 'happy' -> 'random' -> 'sad'.
Loop in the list values, check if it seen in previous action, if not found, add it to the final list, add it to seen_values.
seen_values = set()
for key in ('happy', 'random', 'sad'):
final_list = []
for value in dict[key]:
if value in seen_values:
continue
seen_values.add(value)
final_list.append(value)
dict[key] = final_list

Check if a dictionary has a particular value in it and insert a new item after the matching value to it

I have a list of dictionaries, and i am trying to check if each individual dictionaries in the list contain a particular value and then if the value matches, insert a new item to the matching dictionary.
emp_name = "Jack"
my_list = [{'name':'Jack', 'age':'42', 'j_id':'1'}, {'name':'charles', 'age':'32', 'j_id':'34'}, {'name':'john', 'age':'44', 'j_id':'3'}, {'name':'jacob', 'age':'24', 'j_id':'5'}]
for item in my_list:
name = item.get('name')
print(name)
if name == emp_name:
item['date'] = "something"
print(item)
# add this item value to the dictionary
else:
print("not_matching")
Here is my expected output:
[{'name':'Jack', 'age':'42', 'j_id':'1', 'date':'something'},
{'name':'charles', 'age':'32', 'j_id':'34'}, {'name':'john', 'age':'44',
'j_id':'3'}, {'name':'jacob', 'age':'24', 'j_id':'5'}]
Is there any other pythonic way to simplify this code?
Here's a simplified version of the for loop.
for item in my_list:
if 'name' in item and item['name'] == emp_name:
item['date'] = 'something'
EDIT: Alternate solution (as suggested by #brunodesthuilliers below) - is to use dict's get() method (more details in comments section below).
for item in my_list:
if item.get("name", "") == emp_name:
item['date'] = 'something'

Making a dictionary of from a list and a dictionary

I am trying to create a dictionary of codes that I can use for queries and selections. Let's say I have a dictionary of state names and corresponding FIPS codes:
statedict ={'Alabama': '01', 'Alaska':'02', 'Arizona': '04',... 'Wyoming': '56'}
And then I have a list of FIPS codes that I have pulled in from a Map Server request:
fipslist = ['02121', '01034', '56139', '04187', '02003', '04023', '02118']
I want to sort of combine the key from the dictionary (based on the first 2 characters of the value of that key) with the list items (also, based on the first 2 characters of the value of that key. Ex. all codes beginning with 01 = 'Alabama', etc...). My end goal is something like this:
fipsdict ={'Alabama': ['01034'], 'Alaska':['02121', '02003','02118'], 'Arizona': ['04187', '04023'],... 'Wyoming': ['56139']}
I would try to set it up similar to this, but it's not working quite correctly. Any suggestions?
fipsdict = {}
tempList = []
for items in fipslist:
for k, v in statedict:
if item[:2] == v in statedict:
fipsdict[k] = statedict[v]
fipsdict[v] = tempList.extend(item)
A one liner with nested comprehensions:
>>> {k:[n for n in fipslist if n[:2]==v] for k,v in statedict.items()}
{'Alabama': ['01034'],
'Alaska': ['02121', '02003', '02118'],
'Arizona': ['04187', '04023'],
'Wyoming': ['56139']}
You will have to create a new list to hold matching fips codes for each state. Below is the code that should work for your case.
for state,two_digit_fips in statedict.items():
matching_fips = []
for fips in fipslist:
if fips[:2] == two_digit_fips:
matching_fips.append(fips)
state_to_matching_fips_map[state] = matching_fips
>>> print(state_to_matching_fips_map)
{'Alabama': ['01034'], 'Arizona': ['04187', '04023'], 'Alaska': ['02121', '02003', '02118'], 'Wyoming': ['56139']}
For both proposed solutions I need a reversed state dictionary (I assume that each state has exactly one 2-digit code):
reverse_state_dict = {v: k for k,v in statedict.items()}
An approach based on defaultdict:
from collections import defaultdict
fipsdict = defaultdict(list)
for f in fipslist:
fipsdict[reverse_state_dict[f[:2]]].append(f)
An approach based on groupby and dictionary comprehension:
from itertools import groupby
{reverse_state_dict[k]: list(v) for k,v
in (groupby(sorted(fipslist), key=lambda x:x[:2]))}

how to maintain the keys in TransformDict in python

https://github.com/fluentpython/example-code/blob/master/03-dict-set/transformdict.py
I see the demo:
'''Dictionary that calls a transformation function when looking
up keys, but preserves the original keys.
>>> d = TransformDict(str.lower)
>>> d['Foo'] = 5
>>> d['foo'] == d['FOO'] == d['Foo'] == 5
True
>>> set(d.keys())
{'Foo'}
'''
but , i dont know the object how to maintain the keys.
thanks
I really want to ask how the keys method works
It keeps 2 dictionaries, 1 for the keys and one for the values see getitem in line 51:
def getitem(self, key):
'D.getitem(key) -> (stored key, value)'
transformed = self._transform(key)
original = self._original[transformed] # original keys!
value = self._data[transformed] # values!
return original, value

Adding dictionary values to a list?

I have the following:
list_of_values = []
x = { 'key1': 1, 'key2': 2, 'key3': 3 }
How can I iterate through the dictionary and append one of those values into that list? What if I only want to append the value of 'key2'.
If you only want to append a specific set of values you don't need to iterate through the dictionary can simply add it to the list
list_of_values.append(x["key2"])
However, if you insist on iterating through the dictionary you can iterate through the key value pairs:
for key, value in x.items():
if key == "key2":
list_of_values.append(value)
If you really want to iterate over the dictionary I would suggest using list comprehensions and thereby creating a new list and inserting 'key2' :
list_of_values = [x[key] for key in x if key == 'key2']
because that can be easily extended to search for multiple keywords:
keys_to_add = ['key2'] # Add the other keys to that list.
list_of_values = [x[key] for key in x if key in keys_to_add]
That has the simple advantage that you create your result in one step and don't need to append multiple times. After you are finished iterating over the dictionary you can append the list, just to make it interesting, you can do it without append by just adding the new list to the older one:
list_of_values += [x[key] for key in x if key in keys_to_add]
Notice how I add them in-place with += which is exactly equivalent to calling list_of_values.append(...).
list_of_values = []
x = { 'key1': 1, 'key2': 2, 'key3': 3 }
list_of_values.append(x['key2'])

Resources