I'm working with Python dictionaries and there's something I don't understand when I use the function dict.values() and dict.keys().
Why do they give as a result also the "description" of the function? Am I missing something here?
participant = {"name": "Lisa", "age": 16, "activities": [{"name": "running", "duration": 340},{"name": "walking", "duration": 790}]}
print(participant.values())
print(participant.keys())
The print gives these results:
dict_values([[{'duration': 340, 'name': 'running'}, {'duration': 790, 'name': 'walking'}], 'Lisa', 16])
dict_keys(['activities', 'name', 'age'])
I don't want 'dict_values' and 'dict_keys' in the result. What am I doing wrong?
For this purpose you can use keyword list:
list(participant.keys()) # ['name', 'activities', 'age']
list(participant.values())
# ['Lisa', [{'name': 'running', 'duration': 340}, {'name': 'walking', 'duration': 790}], 16]
Related
I have a dictionary of dictionaries.
Sample:
keyList = ['0','1','2']
valueList = [{'Name': 'Nick', 'Age': 39, 'Country': 'UK'}, {'Name': 'Steve', 'Age': 19, 'Country': 'Spain'}, {'Name': 'Dave', 'Age': 23, 'Country': 'UK'}]
d = {}
for i in range(len(keyList)):
d[keyList[i]] = valueList[i]
Output:
{'0': {'Name': 'Nick', 'Age': 39, 'Country': 'UK'}, '1': {'Name': 'Steve', 'Age': 19, 'Country': 'Spain'}, '2': {'Name': 'Dave', 'Age': 23, 'Country': 'UK'}}
I want to do two things:
filter by one string or int value in a value e.g. Name, ignoring case. I.e. remove any key/value where a string/int is found. So if 'Nick' is found in Name, remove the key '0' and its value completely:
{'1': {'Name': 'Steve', 'Age': 19, 'Country': 'Spain'}, '2': {'Name': 'Dave', 'Age': 23, 'Country': 'UK'}}
The same as above, but with a list of strings instead. I.e. filter and remove any keys where any of the following strings ["uK", "Italy", "New Zealand"] appear in Country, ignoring case.
{'1': {'Name': 'Steve', 'Age': 19, 'Country': 'Spain'}}
I was hoping the below would work for one string, but I think it only works if it is just one dictionary rather than a dictionary of dictionaries, so its not working for me:
filtered_d = {k: v for k, v in d.items() if "nick".casefold() not in v["Name"]}
Any suggestions? Many thanks
Assuming there is one level of nesting in the dictionary (not a dictionary of dictionaries of dictionaries), you could use the following function which iterates over the keys and filters as per the supplied values:
from typing import List
def remove_from_dict(key_name: str, values: List[str], dictionary: dict):
values = [value.casefold() for value in values]
filtered_dict = {
key: inner_dict
for key, inner_dict in dictionary.items()
if inner_dict[key_name].casefold() not in values
}
return filtered_dict
dictionary = {
"0": {"Name": "Nick", "Age": 39, "Country": "UK"},
"1": {"Name": "Steve", "Age": 19, "Country": "Spain"},
"2": {"Name": "Dave", "Age": 23, "Country": "UK"},
}
# Output: {'1': {'Name': 'Steve', 'Age': 19, 'Country': 'Spain'}, '2': {'Name': 'Dave', 'Age': 23, 'Country': 'UK'}}
print(remove_from_dict("Name", ["Nick"], dictionary))
# Output: {'1': {'Name': 'Steve', 'Age': 19, 'Country': 'Spain'}}
print(remove_from_dict("Country", ["uK", "Italy", "New Zealand"], dictionary))
Update:
If we want to account for partial matches, we have to use re module.
import re
from typing import List, Optional
dictionary = {
"0": {"Name": "Nick", "Age": 39, "Country": "UK"},
"1": {"Name": "Steve", "Age": 19, "Country": "Spain"},
"2": {"Name": "Dave", "Age": 23, "Country": "UK"},
}
def remove_from_dict(
key_name: str,
values: List[str],
dictionary: dict,
use_regex: Optional[bool] = False,
):
values = [value.casefold() for value in values]
regular_comparator = lambda string: string.casefold() not in values
# if the string matches partially with anything in the list,
# we need to discard that dictionary.
regex_comparator = lambda string: not any(
re.match(value, string.casefold()) for value in values
)
comparator = regex_comparator if use_regex else regular_comparator
filtered_dict = {
key: inner_dict
for key, inner_dict in dictionary.items()
if comparator(inner_dict[key_name])
}
return filtered_dict
# Output: {}, all dictionaries removed
print(remove_from_dict("Country", ["uK", "Spa"], dictionary, use_regex=True))
Hello I have the following list :
Info_Types = [
{'name': 'A'},
{'name': 'B'},
{'name': 'C'}
]
Next, I would like to use this list with a loop in this type of dictionary:
{
"name": Info_Types[i]['name'],
"domainId": "c50d7ff8-0e6d-4132-a528-f286781f017b",
"typeId": "1bf1b4ac-f52f-4ff9-be43-f96d76dff4c1",
"statusId": "00000000-0000-0000-0000-000000005008",
"excludedFromAutoHyperlinking": 'true'
}
The result I want to get is the following:
[{'name': 'A',
'domainId': 'c50d7ff8-0e6d-4132-a528-f286781f017b',
'typeId': '1bf1b4ac-f52f-4ff9-be43-f96d76dff4c1',
'statusId': '00000000-0000-0000-0000-000000005008',
'excludedFromAutoHyperlinking': 'true'},
{'name': 'B',
'domainId': 'c50d7ff8-0e6d-4132-a528-f286781f017b',
'typeId': '1bf1b4ac-f52f-4ff9-be43-f96d76dff4c1',
'statusId': '00000000-0000-0000-0000-000000005008',
'excludedFromAutoHyperlinking': 'true'},
{'name': 'C',
'domainId': 'c50d7ff8-0e6d-4132-a528-f286781f017b',
'typeId': '1bf1b4ac-f52f-4ff9-be43-f96d76dff4c1',
'statusId': '00000000-0000-0000-0000-000000005008',
'excludedFromAutoHyperlinking': 'true'}]
My idea is that I need to use a for loop but I don't really know how to build it. Someone can help me? thanks
It's better to use list comprehension:
result = [
{
"name": name,
"domainId": "c50d7ff8-0e6d-4132-a528-f286781f017b",
"typeId": "1bf1b4ac-f52f-4ff9-be43-f96d76dff4c1",
"statusId": "00000000-0000-0000-0000-000000005008",
"excludedFromAutoHyperlinking": 'true'
}
for name in Info_Types
]
I am new to Pyspark. My code looks something like below. I am not sure why df.collect() is showing None values for all the string values.
>> rdd = sc.parallelize([{'name': 'test', 'age': {"id": 326, "first_name": "Will", "last_name": "Cur"}},
{'name': 'test2', 'age': {"id": 751, "first_name": "Will", "last_name": "Mc"}}])
>> rdd.collect()
[{'name': 'test', 'age': {'id': 326, 'first_name': 'Will', 'last_name': 'Cur'}}, {'name': 'test2', 'age': {'id': 751, 'first_name': 'Will', 'last_name': 'Mc'}}]
>> df = spark.createDataFrame(rdd)
>> df.collect()
[Row(age={'last_name': None, 'first_name': None, 'id': 326}, name='test'), Row(age={'last_name': None, 'first_name': None, 'id': 751}, name='test2')]
For complex data structures, Spark might have difficulty in inferring the schema from the RDD, so you can instead provide a schema to make sure that the conversion is done properly:
df = spark.createDataFrame(
rdd,
'name string, age struct<id:int, first_name:string, last_name:string>'
)
df.collect()
# [Row(name='test', age=Row(id=326, first_name='Will', last_name='Cur')),
# Row(name='test2', age=Row(id=751, first_name='Will', last_name='Mc'))]
I have a JSON:
[{'job': 'fireman', 'salary': 30000', 'country':'USA'}, {'job': 'doctor', 'salary': '50000': 'country': 'Canada'},{'job': 'fireman', 'salary': 60000', 'country':'France'}, {'job': 'Engineer', 'salary': 45000', 'country':'Mexico'} ]
I want to combine the duplicate values and create a JSON like:
[
{"job": "fireman",
"sumamry": [{"country": "USA", "Salary": 40000}, {"Country": "France", "Salary": 60000}]
"total" : 100000},
{"job": "doctor",
"summary": [{"country": "Canada", "Salary": 50000}]
"total" : 50000},
....
]
Try this:
non_summarized = [{'job': 'fireman', 'salary': 30000, 'country':'USA'}, {'job': 'doctor', 'salary': 50000, 'country': 'Canada'},{'job': 'fireman', 'salary': 60000, 'country':'France'}, {'job': 'Engineer', 'salary': 45000, 'country':'Mexico'}]
# sort the list of dictionary base on job keys, so we can loop in the order
non_summarized = sorted(non_summarized, key = lambda i: i['job'])
summarized = list()
last_value = dict()
for d in non_summarized:
# check if the last value has the same job or not
# if not then create a new dict value and update with new information
if last_value.get('job') != d.get('job'):
last_value = {
'job': d.get('job'),
'total': 0,
'summary': list()
}
summarized.append(last_value)
last_value['total'] += d.get('salary', 0)
last_value['summary'].append({
'country': d.get('country'),
'salary': d.get('salary')
})
print(summarized)
Please let me know if you need any clarification.
Hi guys I'm pretty lost with this simple problem. I have a dictionary and a list of dictionaries in python and I want to loop over the list to add each dictionary to the first dictionary but somehow it just adds the last dictionary with the solution I came up with. I'm using Python 3.6.5
This is what I've tried:
res = []
dictionary = {"id": 1, "name": "Jhon"}
dictionary_2 = [
{"surname": "Doe", "email": "jd#example.com"},
{"surname": "Morrison", "email": "jm#example.com"},
{"surname": "Targetson", "email": "jt#example.com"}
]
for info in dictionary_2:
aux_dict = dictionary
aux_dict["extra"] = info
res.append(aux_dict)
print(res)
What I expect is:
[{'id': 1, 'name': 'Jhon', 'extra': {'surname': 'Doe', 'email': 'jd#example.com'}},
{'id': 1, 'name': 'Jhon', 'extra': {'surname': 'Morrison', 'email': 'jm#example.com'}},
{'id': 1, 'name': 'Jhon', 'extra': {'surname': 'Targetson', 'email': 'jt#example.com'}}]
And this is what I get
[{'id': 1, 'name': 'Jhon', 'extra': {'surname': 'Targetson', 'email': 'jt#example.com'}},
{'id': 1, 'name': 'Jhon', 'extra': {'surname': 'Targetson', 'email': 'jt#example.com'}},
{'id': 1, 'name': 'Jhon', 'extra': {'surname': 'Targetson', 'email': 'jt#example.com'}}]
This is probably a duplicate of some other question but I can't manage to find it
This is because you keep adding the same aux_dict to res.
What you probably want to do is make a copy of dictionary; just assigning it to aux_dict does not make a copy.
This is how you make a (shallow) copy:
aux_dict = dictionary.copy()
That would be sufficient in your case.
You can achieve this in one line using list comprehension and dict constructor:
dictionary = {"id": 1, "name": "Jhon"}
dictionary_2 = [
{"surname": "Doe", "email": "jd#example.com"},
{"surname": "Morrison", "email": "jm#example.com"},
{"surname": "Targetson", "email": "jt#example.com"}
]
# ...
res = [dict(dictionary, extra=item) for item in dictionary_2]
# ...
print(res)