2017-08-01 115 views
1

我有一個字典列表。我想要年齡小於25歲的人的平均年齡。字典列表中值的子集的平均值

我知道我的除數是錯誤的,但我不確定如何在理解內部調整它。

我得到81/8 = 10.125。我應該得到81/5 = 16.2。我如何得到除數以匹配要添加的元素的數量?

people = [{'name': 'John', 'age': 47, 'hobbies': ['Python', 'cooking', 'reading']}, 
      {'name': 'Mary', 'age': 16, 'hobbies': ['horses', 'cooking', 'art']}, 
      {'name': 'Bob', 'age': 14, 'hobbies': ['Python', 'piano', 'cooking']}, 
      {'name': 'Sally', 'age': 11, 'hobbies': ['biking', 'cooking']}, 
      {'name': 'Mark', 'age': 54, 'hobbies': ['hiking', 'camping', 'Python', 'chess']}, 
      {'name': 'Alisa', 'age': 52, 'hobbies': ['camping', 'reading']}, 
      {'name': 'Megan', 'age': 21, 'hobbies': ['lizards', 'reading']}, 
      {'name': 'Amanda', 'age': 19, 'hobbies': ['turtles']}, 
      ] 


print(float(sum(d['age'] for d in people if d['age'] < 25))/len(people)) 

回答

1

而不是做這一切在一個列表理解的,我把它分解成兩個命令,像這樣:

>>> under_25 = [x['age'] for x in people if x['age'] < 25] 
>>> avg_age = sum(under_25)/float(len(under_25)) 

做這一切在一個列表理解會要求你做兩次(分子總和一次,分母長度一次)。我認爲這也更具可讀性。

你甚至可以嘗試做它在一個for循環:

count = 0 
s = 0 
for person in people: 
    if person['age'] < 25: 
     s += person['age'] 
     count += 1 
avg_age = float(s)/count 
2

最簡單的辦法是使用numpy一個條件列表理解:

import numpy as np 

>>> np.mean([p['age'] for p in people if 'age' in p and p['age'] < 25]) 
16.199999999999999 

使用純Python解決方案,在評估集合中的每個元素時,應該跟蹤總數和計數。這減少了內存佔用,因爲您不需要存儲所有符合條件的值。請注意,我在枚舉中使用了一個生成器。

total_age = 0. 
for n, age in enumerate((p['age'] for p in people if 'age' in p and p['age'] < 25), start=1): 
    total_age += age 
>>> print(total_age/n) 
16.2 
1

Python有statistics模塊包含mean功能:

>>> from statistics import mean 
>>> mean(d['age'] for d in people if d['age'] < 25) 
16.2 

或者,如果你有pandas你可以用布爾索引做到這一點:

>>> import pandas as pd 

>>> df = pd.DataFrame(people, columns=['name', 'age', 'hobbies']) 
>>> df[df['age'] < 25]['age'].mean() 
16.2 

df[df['age'] < 25]只包含那些年齡低於25歲的行和['age'].mean()然後計算「年齡」欄。