Creating a list of dictionaries results in a list of copies of the same dictionary
You are not creating a separate dictionary for each iframe, you just keep modifying the same dictionary over and over, and you keep adding additional references to that dictionary in your list.
Remember, when you do something like content.append(info)
, you aren't making a copy of the data, you are simply appending a reference to the data.
You need to create a new dictionary for each iframe.
for iframe in soup.find_all('iframe'):
info = {}
...
Even better, you don't need to create an empty dictionary first. Just create it all at once:
for iframe in soup.find_all('iframe'):
info = {
"src": iframe.get('src'),
"height": iframe.get('height'),
"width": iframe.get('width'),
}
content.append(info)
There are other ways to accomplish this, such as iterating over a list of attributes, or using list or dictionary comprehensions, but it's hard to improve upon the clarity of the above code.
Creating a list of dictionaries with same keys?
When you append the dictionary person to the list people you are just appending a reference to the dictionary to the list, so the list ends up containing just references to the SAME dictionary.
Since each time through the loop you overwrite the dictionary with new values, at the end the list contains just references to the last person you appended.
What you need to do is create a new dictionary for every person, for example:
for human in humans:
number_people, people_data = People.data()
person = dict()
person['name'] = human.name
person['age'] = human.age
person['Sex'] = human.name
people.append(person)
How to generate a list of dictionaries from a list of keys and the same value
If you want something really simple, you can use a list comprehension:
data = ['dog', 'cat']
my_list = [3423, 77813, 12, 153, 1899]
result = [{k:data} for k in my_list]
print(result)
# [{3423: ['dog', 'cat']}, {77813: ['dog', 'cat']}, {12: ['dog', 'cat']}, {153: ['dog', 'cat']}, {1899: ['dog', 'cat']}]
Additionally, here is an example of adding/removing values with the very convienient defaultdict
:
from collections import defaultdict
my_list = [3423, 77813, 12, 153, 1899]
new_list = []
for number in my_list:
# create the defaultdict here
d = defaultdict(list)
# add some data
d[number] += ['dog', 'cat', 'kitten']
# remove some data
d[number].remove('kitten')
# append dictionary
new_list.append(dict(d))
print(new_list)
Which outputs:
[{3423: ['dog', 'cat']}, {77813: ['dog', 'cat']}, {12: ['dog', 'cat']}, {153: ['dog', 'cat']}, {1899: ['dog', 'cat']}]
Using a defaultdict
here is helpful, as it initializes each entry in the dictionary with an empty list. If you don't want to do this, you could achieve this with a normal dictionary, as shown in your question, but this requires you to initialize the empty lists yourself.
How to create a list of dictionaries from a list of keys and a list of values
Good use case for list comprehension
:
dlist = [{k: v} for k, v in zip(celebr, perc)]
Output:
>>> celebr = ['Tony', 'Harry', 'Katty', 'Sam']
>>> perc = [69, 31, 0, 0]
>>>
>>> [{k: v} for k, v in zip(celebr, perc)]
[{'Tony': 69}, {'Harry': 31}, {'Katty': 0}, {'Sam': 0}]
How to get values from a list of dictionaries, which themselves contain lists of dictionaries in Python
First: dict
's require a key-value association for every element in the dictionary. Your 2nd level data structure though does not include keys: ({[{'tag': 'tag 1'}]}
) This is a set
. Unlike dict
's, set
's do not have keys associated with their elements. So your data structure looks like List[Set[List[Dict[str, str]]]]
.
Second: when I try to run
# python 3.8.8
player_info = [{[{'tag': 'tag 1'}]},
{[{'tag': 'tag 2'}]}]
I recieve the error TypeError: unhashable type: 'list'
. That's because you're code attempts to contain a list inside a set. Set membership in python demands the members to be hashable. However, you will not find a __hash__()
function defined on list
objects. Even if you resolve this by replacing the list
with a tuple
, you will find that dict
objects are not hashable either. Potential solutions include using immutable objects like frozendict
or tuple
, but that is another post.
To answer your question, I have reformulated your problem as
player_info = [[[{'tag': 'tag 1'}]],
[[{'tag': 'tag 2'}]]]
and compared the performance difference with A) explicit loops:
for i in range(len(player_info)):
print(player_info[i][0][0]['tag'])
against B) list comprehension
[
print(single_player_info[0][0]['tag'])
for single_player_info in player_info
]
Running the above code blocks in jupyter with the %%timeit
cell magic, I got:
A) 154 µs ± 14.6 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
and
B) 120 µs ± 11 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
Note: This experiment is highly skewed for at least two reasons:
- I tested both trials using only the data you provided (N=2). It is very likely that we would observe different scaling behaviors than initial conditions suggest.
print
consumes a lot of time and makes this problem heavily subject to the status of the kernel
I hope this answers your question.
Sum the values of dictionaries inside a list where the keys are the same
IIUC this is pretty straight forward. You just write a function to sum up all values per key. Then apply it to the transposed list of lists of dicts.
def sum_by_key(dicts):
result = {}
for d in dicts:
for k, v in d.items():
result[k] = result.get(k, 0) + v
return result
lists_of_dicts = [[{1:2, 3:4}, {1:10, 2:9}], [{3:8, 2:4}, {3:1, 2:5}]]
result = [sum_by_key(dicts) for dicts in zip(*lists_of_dicts)]
print(result)
(lists_of_dicts
would be [A, B, C, D]
with your variables)
Output:
[{1: 2, 3: 12, 2: 4}, {1: 10, 2: 14, 3: 1}]
edit: with your new sample data
lists_of_dicts = [A, B, C, D]
result = [sum_by_key(dicts) for dicts in zip(*lists_of_dicts)]
print(result)
produces
[{'1': 1158, '2': 1450, '3': 542, '4': 2060}, {'1': 702, '2': 2600, '3': 1169, '4': 1670}, {'1': 880, '2': 2480, '3': 2000, '4': 3852}, {'1': 600, '2': 640, '3': 1142, '4': 6230}]
Related Topics
Python How to Parse CSS File as Key Value
How to Highlight Searched Queries in Result Page of Django Template
Displaying Subprocess Output to Stdout and Redirecting It
Permanent Fix for Opencv Videocapture
I Can't Import Python Modules in Xcode 11 Using Pythonkit
Generate Correlated Data in Python (3.3)
Generating HTML Documents in Python
Understand the Find() Function in Beautiful Soup
Opencv Videocapture and Error: (-215:Assertion Failed) !_Src.Empty() in Function 'Cv::Cvtcolor'
How to Plot and Annotate a Grouped Bar Chart
How to Edit Header Row in Pandas - Styling
How to Style Gtkbox Margin/Padding with CSS Only
Difference in Boto3 Between Resource, Client, and Session
What Are Some Good Python Orm Solutions
How to Get Value Counts for Multiple Columns at Once in Pandas Dataframe