例如有如下列表: a = [ {'name':'zhangsan', 'score':20}, {'name':'lisi', 'score':25}, {'name':'zhangsan', 'score':30} ]
想要结果: a = [ {'name': 'zhangsan', 'score':20, 'freq':2}, {'name': 'lisi', 'score': 25, 'freq':1} ]
1
veelog 2018-01-27 14:51:44 +08:00 via iPhone 1
reduce 把 list 专为 dict
|
2
coolair 2018-01-27 14:52:25 +08:00 via Android 1
Counter
|
3
rookiebulls 2018-01-27 21:59:28 +08:00 via iPhone
用 set
|
4
jxie0755 2018-01-28 09:58:01 +08:00 1
用 set 会把顺序搞没了,所以最好的办法是在 set 之后,再 sorted 一次变回 list,但是 key 用原来的 index:
print(sorted(set(a), key=a.index)) |
5
zzth370 2018-01-28 11:03:21 +08:00 1
a = [{'name': 'zhangsan', 'score': 20}, {'name': 'lisi', 'score': 25}, {'name': 'zhangsan', 'score': 30}]
b = [{'name': item['name']} for item in a] c = {item['name'] for item in a} d = [{'name': item['name'], 'score': item['score'], 'freq': b.count({'name': item['name']})} for item in a] e = [] for item in d: if item['name'] in c: e.append(item) c.remove(item['name']) print(e) 效果能实现,但感觉代码有点臃肿 |
6
xpresslink 2018-01-28 20:20:17 +08:00 1
@zzth370 确实有点,关键是用 count 会效率低的吓人。
真心看不下去了,我又写了一个。 #!/usr/bin/env python3.6 # -*- coding: utf-8 -*- from collections import OrderedDict a = [ {'name':'zhangsan', 'score': 20}, {'name':'lisi', 'score':25}, {'name':'zhangsan', 'score':30} ] b = OrderedDict() for item in a: b.setdefault(item['name'], {**item, 'freq':0})['freq'] += 1 print(b.values()) # odict_values([{'name': 'zhangsan', 'score': 20, 'freq': 2}, {'name': 'lisi', 'score': 25, 'freq': 1}]) |
7
Binb OP @xpresslink 学到了,这种 sao 操作哪里学来的?只适用于 3.5 之后版本
|
8
thautwarm 2018-01-29 03:28:41 +08:00 2
说实话你这需求不太对。。。
a = [ {'name':'zhangsan', 'score':20}, {'name':'lisi', 'score':25}, {'name':'zhangsan', 'score':30} ]的结果怎么看怎么是 [ ({'name': 'zhangsan', 'score':20}, 2), ({'name': 'lisi', 'score': 25}, 1) ] 正常。 所以我比较偏向 [(a[idx], count) for _, idx, count in zip(*np.unique(list(map(lambda _: _['name'], a)), return_index=True, return_counts=True))] 当然你喜欢 [{**a[idx], 'freq':count} for _, idx, count in zip(*np.unique(list(map(lambda _: _['name'], a)), return_index=True, return_counts=True))] 嘛 |
9
thautwarm 2018-01-29 03:31:37 +08:00
按照先后 index 发现的顺序
[{**a[idx], 'freq':count} for _, idx, count in sorted(zip(*np.unique(list(map(lambda _: _['name'], a)), return_index=True, return_counts=True)), key=lambda x: x[1])] |
10
xpresslink 2018-01-29 10:02:59 +08:00
@Binb 我感觉能写到我这个程度只能说是对 Python 初窥门径,很多是时候解决问题的能力并不是学来的,而是练功一样的积累出来的。推荐你精读《 Python Cook Book 3 》,《流畅的 Python 》,《 Python 标准库》这三本。
|
11
xpresslink 2018-01-29 10:09:56 +08:00
@Binb 只有**item 这个语法糖是 3.5 以后的,以前版本写成 dict(item, freq=0)
|
12
IWTW 2018-01-29 11:16:11 +08:00
@xpresslink 那请问 我要让 zhangsan sorce 的值 永远保持最新的值 如何写呢
|
13
cocoakekeyu 2018-01-29 12:24:32 +08:00
```python
def dedupe2(itmes, key=None): seen = set() for item in items: val = item if key is None else key(item) if val not in seen: yield item seen.add(item) ``` key 换成 operator.getitem('name') |
14
xpresslink 2018-01-29 12:44:36 +08:00
@IWTW 这样问题也问?直接多个 update 步骤就行了啊
for item in a: temp = b.setdefault(item['name'], {**item, 'freq': 0}) temp.update(**item) temp['freq'] += 1 |
16
zzth370 2018-01-29 15:41:58 +08:00
@xpresslink 感谢指点,学习了
|