- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个文本格式的日期时间排序列表。每个条目的格式是'2009-09-10T12:00:00'。
我想找到最接近目标的条目。条目数比我必须执行的搜索数要多得多。
我可以将每个条目更改为一个数字,然后按数字搜索(例如 these 方法),但这似乎过于费力。
有没有比这更好的方法:
def mid(res, target):
#res is a list of entries, sorted by dt (dateTtime)
#each entry is a dict with a dt and some other info
n = len(res)
low = 0
high = n-1
# find the first res greater than target
while low < high:
mid = (low + high)/2
t = res[int(mid)]['dt']
if t < target:
low = mid + 1
else:
high = mid
# check if the prior value is closer
i = max(0, int(low)-1)
a = dttosecs(res[i]['dt'])
b = dttosecs(res[int(low)]['dt'])
t = dttosecs(target)
if abs(a-t) < abs(b-t):
return int(low-1)
else:
return int(low)
import time
def dttosecs(dt):
# string to seconds since the beginning
date,tim = dt.split('T')
y,m,d = date.split('-')
h,mn,s = tim.split(':')
y = int(y)
m = int(m)
d = int(d)
h = int(h)
mn = int(mn)
s = min(59,int(float(s)+0.5)) # round to neatest second
s = int(s)
secs = time.mktime((y,m,d,h,mn,s,0,0,-1))
return secs
最佳答案
不推荐“复制和粘贴编码”(将 bisect
的源代码放入您的代码中),因为它会带来各种成本(大量额外的源代码供您测试和维护,难以处理您复制的上游代码的升级等);重用标准库模块的最佳方式就是导入并使用它们。
但是,将字典转换为有意义的可比较条目的一次遍历是 O(N),这(即使遍历的每一步都很简单)最终将耗尽搜索本身的 O(log N) 时间。由于 bisect
不能像 sort
那样支持 key=
键提取器,解决这个难题的方法是什么——如何重用 bisect
通过导入和调用,没有初步的 O(N) 步骤...?
引用here ,解决方案是大卫惠勒的名言,“计算机科学中的所有问题都可以通过另一个间接层次来解决”。考虑例如......:
import bisect
listofdicts = [
{'dt': '2009-%2.2d-%2.2dT12:00:00' % (m,d) }
for m in range(4,9) for d in range(1,30)
]
class Indexer(object):
def __init__(self, lod, key):
self.lod = lod
self.key = key
def __len__(self):
return len(self.lod)
def __getitem__(self, idx):
return self.lod[idx][self.key]
lookfor = listofdicts[len(listofdicts)//2]['dt']
def mid(res=listofdicts, target=lookfor):
keys = [r['dt'] for r in res]
return res[bisect.bisect_left(keys, target)]
def midi(res=listofdicts, target=lookfor):
wrap = Indexer(res, 'dt')
return res[bisect.bisect_left(wrap, target)]
if __name__ == '__main__':
print '%d dicts on the list' % len(listofdicts)
print 'Looking for', lookfor
print mid(), midi()
assert mid() == midi()
输出(只需运行此 indexer.py
作为检查,然后使用 timeit
,两种方式):
$ python indexer.py
145 dicts on the list
Looking for 2009-06-15T12:00:00
{'dt': '2009-06-15T12:00:00'} {'dt': '2009-06-15T12:00:00'}
$ python -mtimeit -s'import indexer' 'indexer.mid()'
10000 loops, best of 3: 27.2 usec per loop
$ python -mtimeit -s'import indexer' 'indexer.midi()'
100000 loops, best of 3: 9.43 usec per loop
如您所见,即使在列表中有 145 个条目的适度任务中,间接方法的性能也比“ key 提取传递”方法好三倍。由于我们比较的是 O(N) 与 O(log N),间接方法的优势随着 N 的增加而无限制地增长。 (对于非常小的 N,由于间接性导致的更高的乘法常数使 key 提取方法更快,但这很快就被 big-O 差异所超越)。不可否认,Indexer 类是额外的代码——但是,它可以在二进制搜索的所有任务中重复使用,这些任务按每个字典中的一个条目排序的字典列表,因此将它放在你的“容器实用程序后面的技巧”中可以提供很好的返回投资。
主搜索循环就到此为止。对于将两个条目(一个刚好在目标下方和一个刚好在目标上方)和目标转换为秒数的次要任务,再次考虑一种更高重用的方法,即:
import time
adt = '2009-09-10T12:00:00'
def dttosecs(dt=adt):
# string to seconds since the beginning
date,tim = dt.split('T')
y,m,d = date.split('-')
h,mn,s = tim.split(':')
y = int(y)
m = int(m)
d = int(d)
h = int(h)
mn = int(mn)
s = min(59,int(float(s)+0.5)) # round to neatest second
s = int(s)
secs = time.mktime((y,m,d,h,mn,s,0,0,-1))
return secs
def simpler(dt=adt):
return time.mktime(time.strptime(dt, '%Y-%m-%dT%H:%M:%S'))
if __name__ == '__main__':
print adt, dttosecs(), simpler()
assert dttosecs() == simpler()
在这里,重用方法没有性能优势(事实上,相反,dttosecs
更快)——但是,您每次搜索只需要执行三个转换,无论您的字典列表中有多少条目,因此尚不清楚该性能问题是否密切相关。同时,simpler
只需要编写、测试和维护一行简单的代码,而dttosecs
是十几行;鉴于这个比率,在大多数情况下(即排除绝对瓶颈),我更喜欢更简单
。重要的是要了解这两种方法以及它们之间的权衡,以确保做出明智的选择。
关于python - 在表示数字的字符串集合中查找最接近的匹配项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1438924/
我在 GlassFish (J2EE_1.4) 上的 NetBeans 中开发企业项目。我的项目中有一些实体 bean、一些 session bean 和消息驱动 bean。我以如下方式使用 serv
什么在速度方面更好...... 我正在尝试确定用户是否已将某个 URL 添加到他们的快捷方式列表中。如果他们添加了 URL,页面上就会有一个链接,用于从快捷方式中删除该页面,否则他们可以将其添加到快捷
我的问题如下: 我打开一个Excel-File,但我不知道我的客户在模板文件中使用了哪些可能的标头变量。它们可以是:#DATE,#TIME,#NAME等。因此,我需要查找这些变量,以及是否已使用过:替
我有一堆以“-e”结尾的文件要删除。 $ find . -name "*-e" exec rm {} \; find: exec: unknown primary or operator 正则表达式是
我有一个简单的问题:是否可以在 TypeScript 中获取联合的一部分的类型? 例如,您可以经常使用如下查找类型: interface Person { name: string; } type
我正在尝试设置 Point Cloud Library启用 CUDA 选项的主干构建。 我相信我已经按照 these instructions 正确安装了 CUDA . 在 PCL 构建的 cmake
我将首先说我所知道的唯一 VBA 是操作录制的宏的反复试验。我是一名注册会计师,试图以艰难的方式学习 VBA(并希望我去学校学习计算机编程!)。 我有带有多个工作表的大型工作簿。 G 列中以黄色突出显
当文件数达到阈值时,我试图删除目录中最旧的文件。 list_of_files = os.listdir('log') if len([name for name in list_of_files
我有一个数组,它有一些重复的值。 我必须计算每个重复项的数量及其索引。 打印如: Index of b: 1 Index of b: 4 Index of c: 2 Index of c: 3 Ind
我已经搜索了我的问题的解决方案,但没有成功。热键 ctrl+F 找到的 eclipse 查找/替换功能不起作用。注意:通过 Eclipse 菜单 Edit>Find Replace(不工作我的意思是
我想检查 div 是否包含类为“error”的子级,但条件是错误类显示不等于无。 (意味着错误类必须可见。 如何更改我的以下代码: $(".related_field").each(function
这个问题已经有答案了: 已关闭13 年前。 Possible Duplicate: Can jQuery provide the tag name? 嗨! 这个问题太基础了,我不好意思问,但我尝试了
我一直听说这是 cygwin 的路径问题。它阻止了 emacs 在我的 cygwin 中工作。当我在 cli(不是 bash/cygwin)上执行 find 时,无论我输入什么,我都会得到同样的错误。
我正在使用此变量来获取一个或多个与我需要的值相匹配的值。 var mail = $("#dat").contents().find("td:contains('" + name + "')" ).si
请原谅这个长问题。我只是不确定解决这个问题的最佳方法是什么。 我有一个电子表格(Google 表格),其中包含用户和地址列表,我需要从中创建邮寄标签。该电子表格是从我们的学生信息系统导出的。这些地址应
我正在 Excel VBA 中创建一个公式,以解析单元格中以逗号分隔的“部分”列表。在另一个工作表中查找具有该零件名称的单元格,然后使用找到的该单元格的地址来获取同一行不同列的零件成本。我为此工作了数
我被要求在网络应用程序上实现一些电子邮件地址验证 - 我确信我们都已经经历过一千次了...但是,这一次我被要求在域上进行 MX 查找查看它是否接受电子邮件。 有人知道这样做有任何潜在的问题吗? mx
我有一个切换按钮,可读取.wave文件,并且字符串更改为暂停,然后..... 我的问题是,当用户播放声音时,按钮字符串更改为暂停,结束声音后,该字符串仍为暂停状态,我想将其更改为播放。但是我不知道如何
对于令人困惑的标题提前表示歉意。我的问题如下,我在大约 600 个文件中有以下文本: $_REQUEST['FOO'] 我想将其替换为以下内容: $this->input->post('FOO') 为
我正在使用 Ansible 的查找功能查找 INI 文件中的值。这是文档中的示例: - debug: msg="User in integration is {{ lookup('ini', 'use
我是一名优秀的程序员,十分优秀!