需求:需要实现一个有序的集合,像python普通集合一样,除了
它是有序的
我这边穿插着使用了gpt3.5和gpt4,发现确实还是gpt4好用,一分钱一分货啊
问:我的要求是这样,data是一个集合,往里面放了2,1,3,2,3,1后里面的数据应该是2,1,3我希望顺去不乱,同时内容不重复
gpt的回答:
如果常用SortedSet的人能一眼看出来它在胡说八道,实际上SortedSet疑似是排序集合,它实现的是“排序集合”,而不是有序集合,实际上输出的结果是1,2,3,我期望的输出结果是2,1,3
那干脆要求他直接写一个类实现好了
class OrderedSet:
def __init__(self, iterable=None):
self.items = []
self.dict = {}
if iterable is not None:
for item in iterable:
self.add(item)
def __len__(self):
return len(self.items)
def __contains__(self, item):
return item in self.dict
def add(self, item):
if item not in self.dict:
self.dict[item] = None
self.items.append(item)
def discard(self, item):
if item in self.dict:
del self.dict[item]
self.items.remove(item)
def __iter__(self):
return iter(self.items)
看上去好像好还行,就是少了update和remove方法,要求它补上:
def remove(self, item):
if item in self.dict:
del self.dict[item]
self.items.remove(item)
def discard(self, item):
if item in self.dict:
del self.dict[item]
self.items.remove(item)
def clear(self):
self.items = []
self.dict = {}
def pop(self):
if self.items:
item = self.items.pop()
del self.dict[item]
return item
else:
raise KeyError('pop from an empty set')
def update(self, iterable):
for item in iterable:
self.add(item)
把代码丢给gpt4,问它有没有可以优化提速的地方,
from collections import deque
class OrderedSet:
def __init__(self, iterable=None):
self.items = deque()
self.dict = {}
if iterable is not None:
self.update(iterable)
def __len__(self):
return len(self.items)
def __contains__(self, item):
return item in self.dict
def add(self, item):
if item not in self.dict:
node = self.items.append(item)
self.dict[item] = node
def remove(self, item):
if item in self.dict:
node = self.dict[item]
self.items.remove(node)
del self.dict[item]
def discard(self, item):
if item in self.dict:
node = self.dict[item]
self.items.remove(node)
del self.dict[item]
def clear(self):
self.items.clear()
self.dict.clear()
def pop(self):
if self.items:
item = self.items.pop()
del self.dict[item]
return item
else:
raise KeyError('pop from an empty set')
def update(self, *iterables):
for iterable in iterables:
for item in iterable:
self.add(item)
def __iter__(self):
return iter(self.items)
def __str__(self):
return str(list(self.items))
self.items.append(item)实际是没有返回值的会报错,告诉gpt4问它怎么继续改进
from collections import deque
class OrderedSet:
def __init__(self, iterable=None):
self.items = {}
self.order = deque()
if iterable is not None:
self.update(iterable)
def __len__(self):
return len(self.items)
def __contains__(self, item):
return item in self.items
def add(self, item):
if item not in self.items:
self.order.append(item)
self.items[item] = len(self.order) - 1
def remove(self, item):
if item in self.items:
index = self.items[item]
self.order.remove(item)
del self.items[item]
for key, value in self.items.items():
if value > index:
self.items[key] = value - 1
def discard(self, item):
self.remove(item)
def clear(self):
self.items.clear()
self.order.clear()
def pop(self):
if self.order:
item = self.order.pop()
del self.items[item]
return item
else:
raise KeyError('pop from an empty set')
def update(self, *iterables):
for iterable in iterables:
for item in iterable:
self.add(item)
def __iter__(self):
return iter(self.order)
def __str__(self):
return str(list(self.order))
感觉好像没问题,但是一看代码还是不太对劲,remove方法居然要遍历所有元素做判断,那时间复杂度不变成O(n)了,想了下python3.6开始就有有序字典了,直接用字典实现不就完了,哪来那么多花里胡哨的操作?
要求gpt4重写一遍,用dict实现OrderedSet:
class OrderedSet:
def __init__(self, iterable=None):
self.items = {}
if iterable is not None:
self.update(iterable)
def __len__(self):
return len(self.items)
def __contains__(self, item):
return item in self.items
def add(self, item):
if item not in self.items:
self.items[item] = None
def remove(self, item):
if item in self.items:
del self.items[item]
else:
raise KeyError(item)
def update(self, iterable):
for item in iterable:
self.add(item)
def __iter__(self):
return iter(self.items)
def __str__(self):
return str(list(self.items.keys()))
然后问gpt3.5有没有方法实现,让isinstance(OrderedSet,set)为True,
它让我重写__isinstance__
方法,实际上这也是胡说八道,根本就没这个方法。。。
gpt4的回答好点:
实际只要OrderedSet(set)
让它继承set类就能实现了,gpt4的至少回到到继承上了
最后再让它写个测试类测试OrderedSet:
def test_ordered_set():
# 创建一个空的有序集合
ordered_set = OrderedSet()
# 测试添加元素
ordered_set.add(1)
ordered_set.add(2)
ordered_set.add(3)
print("After adding elements:", ordered_set) # Expected output: [1, 2, 3]
# 测试添加重复元素
ordered_set.add(2)
print("After adding duplicate element:", ordered_set) # Expected output: [1, 2, 3]
# 测试更新
ordered_set.update([4, 5, 6])
print("After updating with iterable:", ordered_set) # Expected output: [1, 2, 3, 4, 5, 6]
# 测试使用另一个有序集合更新,其中包含重复元素
another_ordered_set = OrderedSet([3, 4, 5, 6, 7, 8])
ordered_set.update(another_ordered_set)
print("After updating with another OrderedSet:", ordered_set) # Expected output: [1, 2, 3, 4, 5, 6, 7, 8]
# 测试删除元素
ordered_set.remove(4)
print("After removing element:", ordered_set) # Expected output: [1, 2, 3, 5, 6, 7, 8]
if __name__ == "__main__":
test_ordered_set()
总结:gpt3.5大多数时候都在胡说八道,gpt4如果要求详细可以给出可用的代码
个人感觉原因很大在于gpt3.5的输入长度限制死了,导致它其实根本看不到上下文的对话(因为token超4000了),所以大部分时候都在胡说