# 相同类型的实例列表, 实例有一个 `int` 类型的 `num` 属性
ins = [in1, in2, in3, in4, in5, in6, ...]
每个实例都有一个 int
类型的 num
属性, 在 不使用 一些额外库找到 num
相同的, 应该怎么做
# 我的方法
tmp_dict = {}
for i in ins:
if not tmp_dict.get(i.num):
tmp_dict[i.num] = []
tmp_dict[i.num].append(i)
有什么更好的办法吗?
代码里面有比较多的 for
语句, 要不要刻意把这些都 "优化" 成 map
/filter
/... 的语句(算函数式编程吗)?
1
locoz 2023-03-11 08:28:43 +08:00 1
这种常规问题建议直接找 ChatGPT ,它学太多了。
|
2
Trim21 2023-03-11 08:32:57 +08:00 1
问题一 用 collections.defaultdict
|
3
cmdOptionKana 2023-03-11 08:34:13 +08:00 1
建议转为 map/filter 之类的,自己体验一下,这样做一段时间,又使用 for 循环来做类似的事情,此时,你自己就会有非常清晰的判断,哪一种写法更好,因为你都真实体验过了。
|
4
jsjjsyc 2023-03-11 08:38:53 +08:00 via Android 1
问题一用自带库 itertools 的 groupby:
result = groupby(ins, lambda x:x.num) 问题二我也很好奇,不知道这样写能不能提高运行速度,等大佬回答吧🤣 |
5
beeeeeeat 2023-03-11 08:40:12 +08:00 via iPhone 1
1. for 循环里可以用 1 行替换
tmp_dict.setdefault(i.num, []).append(i) 2. 你贴的代码里只有 1 个循环,而且没有收集返回值,不用 map 等方法。如果其他有需要惰性计算的地方可以用。 |
6
icatme 2023-03-11 08:55:42 +08:00
for 遍历查找平均复杂度 n/2 吧, Map 之类查找复杂度一般是 log n, 但添加会有点额外开销
|
7
icatme 2023-03-11 08:58:59 +08:00
抱歉啊, 不熟 python,上面说的不是对 Python 的 .... 没注意看语言
|
8
renmu 2023-03-11 09:23:25 +08:00 via Android
1. 不管怎么找总是要遍历一次,你的实现没什么问题,无非可以用糖少几行代码。
2. 没有必要 |
9
dlsflh 2023-03-11 09:42:17 +08:00 via Android
别整那些花里胡哨的,过几天自己又看不懂了。
|
10
lixiang2017 2023-03-11 14:35:12 +08:00
代码示例
```Python3 from random import choice from collections import defaultdict from itertools import groupby class Instance: def __init__(self, num) -> None: self.num = num arr = list(range(4)) instances = [Instance(choice(arr)) for _ in range(10)] print("values ", [instance.num for instance in instances]) # values [3, 2, 3, 2, 3, 1, 3, 1, 3, 2] # use defaultdict pair1 = defaultdict(list) for instance in instances: pair1[instance.num].append(instance) # use groupby # wrong! need to sort by num first groups = groupby(instances, lambda instance: instance.num) pair2 = {x: list(g) for x, g in groups} assert pair1 != pair2 # also probably equal # use groupby # wrong! need to sort by num first instances.sort(key=lambda instance: instance.num) groups2 = groupby(instances, lambda instance: instance.num) pair3 = {x: list(g) for x, g in groups2} assert pair1 == pair3 ``` |
11
lixiang2017 2023-03-11 14:39:05 +08:00
v2 貌似不支持 markdown
https://pastebin.com/XTnpF56F |
12
lixiang2017 2023-03-11 14:45:00 +08:00 1
再说点别的。
1. not tmp_dict.get(i.num) 是有问题的。i.num 可能为 0, not tmp_dict.get(i.num) 此时为 True 。 变量命名尽量不要用 tmp ,尽量用有实际意义。i 一般是用作索引下标,建议别混用。 2. 最内层的一两层倒也可以简写。多层就不建议了。python 这几个 built-in 的语法糖不是链式的,多层嵌套反而降低可读性。 |
13
lixiang2017 2023-03-11 14:53:59 +08:00
呃,上面最后一点的注释写错了。后一个 sort+groupby 是对的
|
14
plko345 OP @lixiang2017 多谢大佬详细的解答
|