Lets say I have a dictionary like this:
myDict = {
1: {
"a": "something",
"b": [0, 1, 2],
"c": ["a", "b", "c"]
},
2: {
"a": "somethingElse",
"b": [3, 4, 5],
"c": ["d", "e", "f"]
},
3: {
"a": "another",
"b": [6, 7, 8],
"c": ["g", "h", "i"]
}
}
And this is my code:
for id, obj in myDict.items():
for key, val in obj.items():
if key is "b":
for item in val:
# apply some function to item
Is there a better way to iterate over a list inside a nested dict? Or is there a pythonic way to do this?
You absolutely do not need to iterate the list to print it (unless this is a functional requirement for the code you are writing).
Very simply, you could do this:
for id, obj in myDict.items():
if "b" in obj:
print obj["b"]
To map the list object, represented by obj['b'] to another function, you can use the map function:
map(foo, obj["b"])
If you're dictionary is always two levels deep, I don't see anything wrong with your approach. In your implementation, I would use key == "b" rather than key is "b". Using is will test for identity (e.g. id(a) == id(b)), while == will test for equality (e.g. a.__eq__(b)). This functions the same way when I test it in IDLE, but it's not a good habit to get into. There's more info on it here: How is the 'is' keyword implemented in Python?
If you want to deal with varying level dictionaries, you could use something like:
def test_dict_for_key(dictionary, key, function):
for test_key, value in dictionary.items():
if key == test_key:
dictionary[key] = type(value)(map(function, value))
if isinstance(value, dict):
test_dict_for_key(value, key, function)
An example usage might be something like:
myDict = {
1: {
"a": "something",
"b": [0, 1, 2],
"c": ["a", "b", "c"]
},
2: {
"a": "somethingElse",
"b": [3, 4, 5],
"c": ["d", "e", "f"]
},
3: {
"a": "another",
"b": [6, 7, 8],
"c": ["g", "h", "i"]
}
}
# adds 1 to every entry in each b
test_dict_for_key(myDict, "b", lambda x: x + 1)
# prints [1, 2, 3]
print(myDict[1]["b"])
I'm a fan of generator expressions.
inner_lists = (inner_dict['b'] for inner_dict in myDict.values())
# if 'b' is not guaranteed to exist,
# replace inner_dict['b'] with inner_dict.get('b', [])
items = (item for ls in inner_lists for item in ls)
Now you can either use a foo loop
for item in items:
# apply function
or map
transformed_items = map(func, items)
A couple fixes could be made.
Don't use is when comparing two strings (if key is "b":)
Simply say print(item) instead of using .format(), since you only have one variable that you're printing, with no additional string formatting
Revised code:
for id, obj in myDict.items():
for key, val in obj.items():
if key == "b":
for item in val:
print(item)
If you are sure that you will have a b key in every case, you can simply do:
for id, obj in myDict.items():
for item in obj["b"]:
print item
Related
Let's say I have a dictionary like below
myDict = {"a": 1, "b": 2, "c": 3, "d": 4}
and I'm trying to get this result
myDict = {"b": 1, "a": 2, "c": 3, "d": 4}
I tried running using
dictionary[new_key] = dictionary.pop(old_key)
But thats just deleting and appending a new key and value to the dictionary. It would result in:
myDict = {"b": 2, "c": 3, "d": 4, "a": 2}
Thanks in advance for the answer
So I understand you aim to preserve the sequence.
Make first a new dictionary that maps the old keys to the new keys:
mapping = {"a": "b", "b": "a"}
Now you can generate the new structure
my_dict = {mapping.get(key, key): value for key, value in my_dict.items()}
The get method here tries to map the key, but uses the key itself, if the key is not in the mapping.
This question already has answers here:
How do I count the occurrences of a list item?
(29 answers)
Closed 10 months ago.
i was trying to keep count of each item in list in python and want to convert it into key-value pairs like json so i can able to iterate over it to present it on frontend using django.
list = ["a" , "a", "c", "b", "c", "d"]
here same i want this list into key value pairs with counting of each item in list
list = [{ "name":"a" , "count":2 } , { "name":"c" , "count":2 , ......}]
Use a set to count the number of each element in the list
l = ["a" , "a", "c", "b", "c", "d"]
d = {val: l.count(val) for val in set(l)}
this will give you :
{'c': 2, 'a': 2, 'b': 1, 'd': 1}
If you want to format the dict as you wrote it in your message (even though it's really inefficient), you can write it like that :
d = [{'name': val, 'count': l.count(val)} for val in set(l)}]
data = ["a" , "a", "c", "b", "c", "d"]
count_list=[{"name":d,"count": data.count(d)} for d in set(data)]
Probably the easiest way to do this:
def dict_count(list):
dict_tot = {}
for i in liste:
dict_tot[i] = liste.count(i)
print(dict_tot)
I am trying to create a Python function that receives a dictionary whose values are inner dictionaries. If the keys of the inner dictionaries are the same, it should return 1, if not it should return 0.
This is the code I tried:
def f(dct: dict) -> int:
for i in range(len(dct)):
for j in range(len(dct)):
dct1 = list(dct.values())
if dct1[i].keys() == dct1[j].keys():
return 1
else:
return 0
it actually worked when the input dictionary have only two inner dictionaries but didn't work for three.
For example:
f(
{
"A": {1: "a", 2: "b"},
"B": {2: "c", 3: "d"},
}
)
returned 0 (which is the result I wanted)
but
f(
{
"A": {1: "a", 2: "b"},
"B": {2: "c", 3: "d"},
"C": {1: "c", 2: "d"},
}
)
returned 1, which is not the result I wanted.
How do I fix it, please?
So you want to ensure all of the dictionaries that are the values of dct have the same keys (ignoring the values)?
def all_key_sets_equal(dct: dict) -> bool:
key_sets = [set(nd) for nd in dct.values()]
return all(key_set == key_sets[0] for key_set in key_sets)
I have one dataset in a list form and I want to convert it into another dataset under certain conditions.
Conditions
"a" = 1
"b" = 2
"c" = 3
input_list = ["a", "b", "c"]
# something happens
output_list = [1, 2, 3]
What to do?
Represent your set of conditions in a dictionary:
conditions = {
"a": 1,
"b": 2,
"c": 3
}
Use that dictionary in order to generate the output:
input_list = ["a", "b", "c"]
output_list = [conditions[x] for x in input_list]
What you want to achieve is a mapping.
Your conditions are a map, dictionary (Python lingo) or hash-table.
Each value there (like 1) corresponds to a key in the dataset (like "a").
To represent this mapping you can use a table-like datastructure that maps a key to a value. In Python this datastructure is called a dictionary:
mapping = {"a": 1, "b": 2, "c": 3} # used to translate from key to value (e.g. "a" to 1)
input_list = ["a", "b", "c"]
# something happens
output_list = []
for v in input_list:
mapped_value = mapping[v] # get the corresponding value, translate or map it
print(v + " -> " + mapped_value)
output_list.append(mapped_value)
print(output_list) # [1, 2, 3]
See also
Map (mathematics) - Wikipedia
Convert numbers into corresponding letter using Python
I have a dict with a dynamical number of nested dicts inside of it, something like:
my_dict = {"a": {"b": {"c: {...}}}}
I need to dynamically move inside this dict, for instance I'd like to do the following:
levels = ["a", "b", "c"]
my_dict[levels[0]][levels[1]][levels[2]] = "something"
where the number of items inside "levels" may vary.
I can partially achieve the same result for a limited number of items inside "levels" by writing something like this:
if len(levels) == 1:
my_dict[levels[0]] = "something"
elif len(levels) == 2:
my_dict[levels[0]][levels[1]] = "something"
elif len(levels) == 3:
my_dict[levels[0]][levels[1]][levels[2]] = "something"
(...)
but I'm looking for a more general and elegant solution.
Is there a way to do this?
There isn't a lot of code here to go on, but for what you have given, you can define
def get(d, keys):
for key in keys:
d = d[key]
return d
def set(d, keys, value):
d = get(d, keys[:-1])
d[keys[-1]] = value
And then use it like this
my_dict = {"a":{"b":{"c":{}}}}
set(my_dict, ["a", "b", "c"], "something")
print get(my_dict, ["a", "b", "c"])
A functional alternative for get:
def get(d, keys):
return reduce(lambda d, key: d[key], keys, d)