Python list of dictionaries search with multiple input - python-3.x

Sorry for such a stupid question but im on deadend right now (1st time using python), how do i search Python list of dictionaries with multiple
attribute ?
My current code is only can search by 1 attribute.
people = [{'name': 'Alex', 'age': '19',
'grade': 80},
{'name': 'Brian', 'age': '17', 'grade':
90},
{'name': 'Junior', 'age': '17', 'grade':
90},
{'name': 'Zoey', 'age': '19', 'grade':
95},
{'name': 'joe', 'age': '18', 'grade':
90}]
entry=input("Check the name you want to search the grade :")
list(filter(lambda person: person['name'] == entry, people))
I want it to search by multitple attribute, so if i input either '17' or 90, the expected output is
[{'name': 'Brian', 'age': '17', 'grade': 90},
{'name': 'Junior', 'age': '17', 'grade': 90}]

You could just use two conditions connected by an or (while taking measures not to compare strings with numbers):
list(filter(lambda person: str(person['grade']) == entry or str(person['grade']) == entry, people))
At some point, a comprehension will be more readable:
[p for p in people if str(person['grade']) == entry or str(p['grade']) == entry]
And if you want to add more search keys, you can further DRY this out, using any:
keys = ('name', 'grade', 'age')
filtered = [p for p in people if any(str(p[k]) == entry for k in keys)]

Related

Comparing dictionary list. TypeError: tuple indices must be integers or slices, not str

I am trying to compare two sets of data (file1,file2) in a dictionary format. When comparing using example 1 (see bellow), the code works but when I add more data (example 2) I get an error as tuple indices must be integer or slices. I'm struggling to understand this, since I'm comparing two sets of dictionaries and not a list to use an integer to compare using integers in the index rather than the name of key in the dictionary.
#Dict list example 1: with this example, it works
file1= {'name': 'Phill', 'age': 42}
file2= {'name': 'Phill', 'age': 22}
#Dict list example 2: with this example, it doesn't work
file1= {'name': 'Phill', 'age': 42},{'name': 'Phill', 'age': 22}
file2= {'name': 'Phill', 'age': 22},{'name': 'Phill', 'age': 52}
#Function with two args
def diffValue (file1,file2) :
for newAge in file1,file2 :
if file1 [ 'age' ] == file2 [ 'age' ] :
# if no difference found in both files within the age field
print ( "No difference found" )
else :
# the age is different. return values name,age where ever there is a difference from file1 only
return newAge
Expected results:
Return {'name': 'Phill', 'age': 42},{'name': 'Phill', 'age': 22}
I think you meant to do something like this:
file1 = {'name': 'Phill', 'age': 42}, {'name': 'Phill', 'age': 22}
file2 = {'name': 'Phill', 'age': 22}, {'name': 'Phill', 'age': 52}
def diff_value(f1, f2):
# Create a list to store the differences
diffs = []
# Iterate for every element in parallel
for v1, v2 in zip(f1, f2):
if v1['age'] == v2['age']:
# If no difference found in both files within the age field
print('No difference found')
else:
# The age is different, append v1 to `diffs`
diffs.append(v1)
return diffs
print(diff_value(file1, file2))
# Output: [{'name': 'Phill', 'age': 42}, {'name': 'Phill', 'age': 22}]
>>> file1= {'name': 'Phill', 'age': 42},{'name': 'Phill', 'age': 22}
>>> file1
({'name': 'Phill', 'age': 42}, {'name': 'Phill', 'age': 22})
>>> type(file1)
<class 'tuple'>
file1 is tuple that is why it gives an error
one way to make it work with your function is:
def diffValue (file1,file2) :
for newAge in file1,file2 :
if file1 [ 'age' ] == file2 [ 'age' ] :
# if no difference found in both files within the age field
print ( "No difference found" )
else :
# the age is different. return values name,age where ever there is a difference from file1 only
return newAge
file1= [{'name': 'Phill', 'age': 42},{'name': 'Phill', 'age': 22}]
file2= [{'name': 'Phill', 'age': 22},{'name': 'Phill', 'age': 52}]
a=""
for i in range(len(file1)):
a+=str(diffValue(file1[i],file2[i]))+","
a=a[:-1]
print(a)

How can I enter a dictionary inside an another empty dictionary?

The example code -
innerdict = {}
outerdict = {}
for line in range(1, 10, 2):
for j in range(1, 10, 2):
line_tuple = ("Item" + str( line ), int( line ))
key = line_tuple[1]
if line ==j:
outerdict[key] = dict( innerdict )
outerdict[key] = {'Name': '{0}'.format( "item"+str(j) ), 'Price': '{0}'.format( j )}
print(outerdict)
The ouput comes out like this-
{1: {'Name': 'item1', 'Price': '1'}, 3: {'Name': 'item3', 'Price': '3'}, 5: {'Name': 'item5', 'Price': '5'}, 7: {'Name': 'item7', 'Price': '7'}, 9: {'Name': 'item9', 'Price': '9'}}
The above output is achievable since it is conventional. I found a lot of online suggestions regarding nested dictionary comprehension.
But I want the output to come out like below-
{{'Name': 'item1', 'Price': '1'}, {'Name': 'item3', 'Price': '3'}, {'Name': 'item5', 'Price': '5'}, {'Name': 'item7', 'Price': '7'}, {'Name': 'item9', 'Price': '9'}}
Thanks in advance!
This is not possible, as the dict objects are not hashable.
{{1:2}} would mean putting a dict {1:2} into a set, which is not possible because of the un-hashability of the objects mentioned above. Better put them in a list:
[{1:2}, {2:3}]
What you want is something like a list of dictionaries. And this {{'Name': 'item1', 'Price': '1'}, {'Name': 'item3', 'Price': '3'}, {'Name': 'item5', 'Price': '5'}, {'Name': 'item7', 'Price': '7'}, {'Name': 'item9', 'Price': '9'}} is invalid as dictionary is considered to be a key-value pair and there is no key in this.
It can be checked by assigning the above to a variable and then checking its type.
d = {{'Name': 'item1', 'Price': '1'}, {'Name': 'item3', 'Price': '3'}, {'Name': 'item5', 'Price': '5'}, {'Name': 'item7', 'Price': '7'}, {'Name': 'item9', 'Price': '9'}}
print(type(d))
It will result in an error saying it's unhashable.

Dict list comprehension in Python

I am a python newbie. I am trying to learn comprehension and I am stuck currently with the scenario. I am able to do this mutation
sample_dict_list = [{'name': 'Vijay', 'age':30, 'empId': 1}, {'name': 'VV', 'age': 10, 'empId': 2},
{'name': 'VV1', 'age': 40, 'empId': 3}, {'name': 'VV2', 'age': 20, 'empId': 4}]
def list_mutate_dict(list1, mutable_func):
for items in list1:
for key,value in items.items():
if(key == 'age'):
items[key] = mutable_func(value)
return
mutable_list_func = lambda data: data*10
list_mutate_dict(sample_dict_list, mutable_list_func)
print(sample_dict_list)
[{'name': 'Vijay', 'age': 300, 'empId': 1}, {'name': 'VV', 'age': 100, 'empId': 2}, {'name': 'VV1', 'age': 400, 'empId': 3}, {'name': 'VV2', 'age': 200, 'empId': 4}]
Dict with key 'age' alone is mutated and returned
THis works fine. But I am trying the same with the single line comprehension. I am unsure if it can be done.
print([item for key,value in item.items() if (key == 'age') mutable_list_func(value) for item in sample_dict_list])
THis is the op - [{'age': 200}, {'age': 200}, {'age': 200}, {'age': 200}] which is incorrect. It just takes in the last value and mutates and returns as a dict list
Could this be done in a "nested" list dict comprehension?
When using comprehensions, you are actually creating a new one so "mutating" falls outside the context. But assuming you want the same output:
mutable_func = lambda data: data*10
print([{**d, "age": mutable_func(d["age"])} for d in sample_dict_list])
In my example you are unpacking the dictionary with **d and adding another key-value which overwrites the existing one in d.
It's a bit complicated but here:
def list_mutate_dict(list1, mutable_func):
[{key: (mutable_func(value) if key == 'age' else value) for key, value in item.items()} for item in list1]
Explanation (going inside out):
First, you mutate the value if needed in the condition inside the assignment, keeping all other values the same.
Then, you do this for all dictionary items by iterating all the items.
And, finally, you do this for all dictionaries in the list.
I will add a caveat that these types of list comprehensions are not considered a best practice and often lead to very confusing and unmaintainable code.

create nested object from records oriented dictionary

I have the following data frame:
[{'Name': 'foo', 'Description': 'foobar', 'Value': '5'}, {'Name': 'baz', 'Description': 'foobaz', 'Value': '4'}, {'Name': 'bar', 'Description': 'foofoo', 'Value': '8'}]
And I'd like to create two nested categories. One category for Name, Description keys and another category for Value key. Example of output for one object:
{'details': {'Name': 'foo', 'Description': 'foobar'}, 'stats': { 'Value': '5' }}
so far I'm only able to achieve this by joining "manually" each items. I'm pretty sure this is not the right solution.
Here is one solution:
data = [{'Name': 'foo', 'Description': 'foobar', 'Value': '5'}, {'Name': 'baz', 'Description': 'foobaz', 'Value': '4'}, {'Name': 'bar', 'Description': 'foofoo', 'Value': '8'}]
df = pd.DataFrame(data)
m = df.to_dict('records')
stats = [{'stats':i.popitem()} for i in m]
details = [{'details':i} for i in m]
g = list(zip(details,stats))
print(*g)
({'details': {'Name': 'foo', 'Description': 'foobar'}}, {'stats': ('Value', '5')}) ({'details': {'Name': 'baz', 'Description': 'foobaz'}}, {'stats': ('Value', '4')}) ({'details': {'Name': 'bar', 'Description': 'foofoo'}}, {'stats': ('Value', '8')})
The major function here is popitem(), which destructively pulls out a pair from the dictionary.
Using list comprehension:
from json import dump
result = [{
'details': {col: row[col] for col in ['Name', 'Description']},
'stat': {col: row[col] for col in ['Value']}
} for row in df.to_dict(orient='records')]
# Write to file
with open('result.json', 'w') as f:
dump(result, f)

Filtering out the values of inner dictionary in Python

I have dictionary,
dict={
{'dept': 'ECE', 'id': 1, 'name': 'asif', 'City': 'Bangalore'},
{'dept': 'ECE', 'id': 2, 'name': 'iqbal', 'City': 'Kolkata'}
}
I wanted to is there any way so that I can filter out the name and dept on the basis of City?
I tried but couldn't find any way out.
Ok, If I understand your question, and from the fact that set has been converted to a list, I think something like that could be what you are looking for:
data=[
{'dept': 'ECE', 'id': 1, 'name': 'asif', 'City': 'Bangalore'},
{'dept': 'ECE', 'id': 2, 'name': 'iqbal', 'City': 'Kolkata'},
]
my_keys = ('name','dept',)
my_cities = ['Kolkata',]
my_dicts = [{key:value for key, value in dictionary.items() if key in my_keys} for dictionary in data if dictionary['City'] in my_cities]
print(my_dicts)

Resources