【发布时间】:2019-04-27 06:17:53
【问题描述】:
我不确定下面代码的 Python 对象模型到底发生了什么。
您可以从此link 下载 ctabus.csv 文件的数据
import csv
def read_as_dicts(filename):
records = []
with open(filename) as f:
rows = csv.reader(f)
headers = next(rows)
for row in rows:
route = row[0]
date = row[1]
daytype = row[2]
rides = int(row[3])
records.append({
'route': route,
'date': date,
'daytype': daytype,
'rides': rides})
return records
# read data from csv
rows = read_as_dicts('ctabus.csv')
print(len(rows)) #736461
# record route ids (object ids)
route_ids = set()
for row in rows:
route_ids.add(id(row['route']))
print(len(route_ids)) #690072
# unique_routes
unique_routes = set()
for row in rows:
unique_routes.add(row['route'])
print(len(unique_routes)) #185
当我调用print(len(route_ids)) 时,它会打印"690072"。为什么 Python 最终会创建这么多对象?
我希望这个计数是 185 或 736461。185,因为当我计算集合中的唯一路线时,该集合的长度为 185。736461 因为这是 csv 文件中的记录总数。
这个奇怪的数字“690072”是什么?
我想了解为什么会出现这种部分缓存?为什么 python 不能执行完整的缓存,如下所示。
import csv
route_cache = {}
#some hack to cache
def cached_route(routename):
if routename not in route_cache:
route_cache[routename] = routename
return route_cache[routename]
def read_as_dicts(filename):
records = []
with open(filename) as f:
rows = csv.reader(f)
headers = next(rows)
for row in rows:
row[0] = cached_route(row[0]) #cache trick
route = row[0]
date = row[1]
daytype = row[2]
rides = int(row[3])
records.append({
'route': route,
'date': date,
'daytype': daytype,
'rides': rides})
return records
# read data from csv
rows = read_as_dicts('ctabus.csv')
print(len(rows)) #736461
# unique_routes
unique_routes = set()
for row in rows:
unique_routes.add(row['route'])
print(len(unique_routes)) #185
# record route ids (object ids)
route_ids = set()
for row in rows:
route_ids.add(id(row['route']))
print(len(route_ids)) #185
【问题讨论】:
-
id 返回对象的内存位置。循环中可能会回收一些内存并重用地址,因此您会得到一个较小的数字。你想达到什么目的?
-
我有太多待修改的内容,但我可以建议将此问题的标题更改为其他人更有可能找到的内容吗?也许,“Python - 比对象少唯一的 ID”,或类似的东西。
-
关于你的编辑:所以最后你问为什么不总是缓存所有不可变对象?
-
@timgeb 是的。我的意思是缓存短比特而不是大比特背后的思考过程。
-
这只是一个猜测。我添加了python-internals标签,也许它吸引了可以权威回答的人。
标签: python string caching python-internals