Python 2.7 为什么使用.index()比使用for循环快?
我想在一个巨大的列表中找到匹配项并返回值。我使用的是:Python 2.7 为什么使用.index()比使用for循环快?,python-2.7,Python 2.7,我想在一个巨大的列表中找到匹配项并返回值。我使用的是: def func(x) for i in list: if i == x: return i return False 令人惊讶的是,将此方法替换为.index后: def func(x): try: return i.index(x) except Valueerror: return False 测试时间缩短了10倍。为什么呢?或者索
def func(x)
for i in list:
if i == x:
return i
return False
令人惊讶的是,将此方法替换为.index后:
def func(x):
try:
return i.index(x)
except Valueerror:
return False
测试时间缩短了10倍。为什么呢?或者索引和for循环之间有什么不同?出于效率原因(至少在Ruby的MRI版本中),数组直接在C中实现,因此速度更快 这是:
静态值
rb_str_index_m(int argc,VALUE*argv,VALUE str)
{
价值子;
值initpos;
长pos;
if(rb_scan_args(argc、argv、11”、&sub和initpos)==2){
pos=NUM2LONG(initpos);
}
否则{
pos=0;
}
如果(位置<0){
pos+=str_strlen(str,NULL);
如果(位置<0){
if(RB_TYPE_P(sub,T_REGEXP)){
rb_backref_集(Qnil);
}
返回Qnil;
}
}
if(特殊常数)转为通用;
开关(内置式(分型)){
案例T_REGEXP:
if(pos>str_strlen(str,NULL))
返回Qnil;
pos=str_偏移量(RSTRING_PTR(str)、RSTRING_END(str)、pos、,
rb_enc_check(str,sub),单字节可优化(str);
pos=rb_reg_搜索(sub,str,pos,0);
pos=rb_str_sublen(str,pos);
打破
通用:
默认值:{
价值tmp;
tmp=rb\u检查\u字符串\u类型(子类型);
如果(无(tmp)){
rb_raise(rb_eTypeError,“类型不匹配:%s已给定”,
rb_obj_类名称(sub));
}
sub=tmp;
}
/*失败*/
案例T_字符串:
pos=rb\U str\U索引(str,sub,pos);
pos=rb_str_sublen(str,pos);
打破
}
如果(pos==-1)返回Qnil;
返回长2纳姆(pos);
}
这仅仅是因为python内置代码是用C实现的,python代码在C代码循环中运行
因此,当您使用一个用C实现的python函数时,它将比用python创建自己的函数版本快得多。
索引很方便(也可能用C实现)。我意识到我的for循环迫使它逐行通过csv文件-谢谢
static VALUE
rb_str_index_m(int argc, VALUE *argv, VALUE str)
{
VALUE sub;
VALUE initpos;
long pos;
if (rb_scan_args(argc, argv, "11", &sub, &initpos) == 2) {
pos = NUM2LONG(initpos);
}
else {
pos = 0;
}
if (pos < 0) {
pos += str_strlen(str, NULL);
if (pos < 0) {
if (RB_TYPE_P(sub, T_REGEXP)) {
rb_backref_set(Qnil);
}
return Qnil;
}
}
if (SPECIAL_CONST_P(sub)) goto generic;
switch (BUILTIN_TYPE(sub)) {
case T_REGEXP:
if (pos > str_strlen(str, NULL))
return Qnil;
pos = str_offset(RSTRING_PTR(str), RSTRING_END(str), pos,
rb_enc_check(str, sub), single_byte_optimizable(str));
pos = rb_reg_search(sub, str, pos, 0);
pos = rb_str_sublen(str, pos);
break;
generic:
default: {
VALUE tmp;
tmp = rb_check_string_type(sub);
if (NIL_P(tmp)) {
rb_raise(rb_eTypeError, "type mismatch: %s given",
rb_obj_classname(sub));
}
sub = tmp;
}
/* fall through */
case T_STRING:
pos = rb_str_index(str, sub, pos);
pos = rb_str_sublen(str, pos);
break;
}
if (pos == -1) return Qnil;
return LONG2NUM(pos);
}