请教:Python怎样最简洁的对一个list的不同元素分别取平均值?

今天面试的时候,遇到一个很简单的问题,但是面试官要求最短的运行时间以及最简洁的写法。

假设list1 = ["张三", "张三", "王五", "张三", "李四"]; list2 = [10, 15, 1, 20, 99]; 所以张三的值是10、15、20(平均值是15),李四的值是99(平均值是99),王五飘过。

题目要求输出也是一个长度为4的list3,它的元素和list1对应,写成[15, 15, 1, 15, 99]。

我第一反应是遍历,然后建立字典,储存所有list1中的不同元素的下标,然后去list2里找对应的数值。但是我觉得这个办法有点笨。

dict=defaultdict(list); mapping={}; list3=[]
for index, item in enumerate(list1):
    dict[item].append(index)   # 生成一个字典 {张:[0,1,3];李:[4];王:[2]}
for key in dict.iterkeys():
    sum = 0; av=0
    for element in dict[key]:
        sum += list2[element];
    av = sum / len(dict[key])
    mapping[key] = av   # 生成另一个字典 {张:15;李:99;王:1}
for index, item in enumerate(list1):
    list3.append(mapping[item])   # 遍历list1来生成list3

面试官问:“假设有一个数值的list4=[10, 20, 30, 40, 50],另有一个下标的list5=[0, 2, 4],要求根据list5找出list4[0]、list4[2]、list4[4]的总和,除了像刚才那样遍历,还有其他方法吗?” 我一时语塞。

所以请教一下大家:
1 把list1中的张、王、李对应的list2中的数值取出,再生成和list1对应的list3,除了像刚才那样建立字典,还有简单其他方法吗?用zip和izip么?
2 把数值list4的元素根据下标list5取出并且运算,除了像刚才那样建立遍历,还有简单其他方法吗?

谢谢了先!

阅读 10k
5 个回答

估计面试官是在考你groupby和map的用法

#第一问
from itertools import groupby

list1 = ["张三", "张三", "王五", "张三", "李四"]
list2 = [10, 15, 1, 20, 99]

data = sorted(zip(list1, list2))
d = dict()
for k, g in groupby(data, key=lambda x: x[0]):
    lst = [v for k, v in g]
    d[k] = sum(lst)//len(lst)

list3 = map(lambda x: d[x], list1)
print list3

#第二问
list4 = [10, 20, 30, 40, 50]
list5 = [0, 2, 4]

print sum(map(lambda x: list4[x], list5))

python3

>>> list1 = ["张三", "张三", "王五", "张三", "李四"]
>>> list2 = [10, 15, 1, 20, 99]
>>> d={}
>>> for k,v in zip(list1,list2):
    d.setdefault(k,[0,0])
    d[k][0]+=1
    d[k][1]+=v
    
>>> list3=[d[k][1]//d[k][0] for k in list1]
>>> list3
[15, 15, 1, 15, 99]

>>> list4 = [10, 20, 30, 40, 50]
>>> list5 = [0, 2, 4]
>>> sum(list4[i] for i in list5)
90
>>> from collections import defaultdict
>>> d = defaultdict(lambda: [0,0])
>>> for name, score in zip(list1, list2):
...   d[name][0] += score
...   d[name][1] += 1
... 
>>> for name, (total_score, n) in d.items():
...   if n > 0:
...     print(f'{name}: {total_score/n}')
... 
张三: 15.0
王五: 1.0
李四: 99.0

import pandas as pd

list1 = ["张三", "张三", "王五", "张三", "李四"]
list2 = [10, 15, 1, 20, 99]
df = pd.DataFrame({'a':list1,'b':list2})
x = dict(df['b'].groupby(df['a']).mean())
list3 = [x['i'] for i in list1]

输出list3 [15, 15, 1, 15, 99]

list4=[10, 20, 30, 40, 50]
list5=[0, 2, 4]
list6 = [list4[i] for i in list5]
输出list6

是不是向考你列表生成式啊

新手上路,请多包涵

可以用pandas的groupby:
pd.DataFrame({'A': list1, 'B':list2}).groupby('A').mean()

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏