Форум сайта python.su
все понятно спасибо огромное ))
но это не все! кто кто может объяснить почему в строке -
if l[bisect.bisect_left(l, v)] == v:
if l == v:вот сам код целиком
IndexError: list index out of range
import bisect
import random
import time
chars = u'qwertyuiopasdfghjklzxcvbnm_01234567890'
def create_word():
w = ''
for n in range(10):
w += random.choice(chars)
return w
def create_list_of_words(count_of_words):
l = []
for i in xrange(count_of_words):
bisect.insort(l, create_word())
return l
def create_list_of_words2(count_of_words):
l = []
for i in xrange(count_of_words):
l.append(create_word())
return l
t = time.time()
l = create_list_of_words(30000)
print '\nQTY1_:%s' % len(l)
print time.time() - t
ls = create_list_of_words2(30000)
print '\nQTY2_:%s' % len(ls)
t = time.time()
for v in ls:
if l[bisect.bisect_left(l, v)] == v:
pass
print time.time() - t
Отредактировано (Авг. 18, 2009 13:37:48)
Офлайн
test157Элемент не найден и должен быть вставлен в конец списка, возвращается индекс за пределами списка
все понятно спасибо огромное ))
но это не все! кто кто может объяснить почему в строке -у меня ИНОГДА вылетает ошибкаif l[bisect.bisect_left(l, v)] == v:
test157ну вот так можно
и как с этим бороться? и я вобще правильно сделал поиск самого элемента?
def in_list(ls, item):
try:
return ls[bisect.bisect_left(ls, item)] == item
except IndexError:
return False
Отредактировано (Авг. 18, 2009 14:09:48)
Офлайн
Да речь действительно шла о трехстах, четырехстах словах =). Просто количество слов, которыее я проверяю на вхождение в эти 300-400 слов измеряется десятками тысяч, поэтому и спросил - что в этом случае будет быстрее, и будет ли вообще существенная разница.
Но все-таки решил использовать sqlite, по условию задачи некоторые слова должны добавляться в словарь контрольных слов и использоваться в дальнейшем =). Поэтому без базы никак.
Офлайн
NSkrypnikА что мешает загрузить слова в словарь из базы? или сохранить словарь в файл через pickle? Используя базу вы сильно потеряете в скорости
Но все-таки решил использовать sqlite, по условию задачи некоторые слова должны добавляться в словарь контрольных слов и использоваться в дальнейшем =). Поэтому без базы никак.
Офлайн
Ок, спасибо. Наверно так и сделаю. Т.е. все-таки обращение к API базы медленнее, чем допустим использование dict(я имею в виду если слово искать на вхождение не оператором in, а допустим has_key?).
Офлайн
ну все - разобрался. чтобы окончательно закрыть вопрос, небольшое сравнение по скорости PHP/Python List/Python Bisect
QTY1_30000 - это означает время затраченное на создание массива из 30 тысяч элементов.
QTY2_30000 - это означает время затраченное на 30 тысяч поисков в созданном массиве, которые берутся из другого массива.
ПАМЯТЬ: сколько весит приложение с массивом в 30 тысяч строк - длина элемента в массиве 101 байт.
======================================================================
значения для PHP 5.2.6-1+lenny3 with Suhosin-Patch 0.9.6.2 (cli)
ПАМЯТЬ: 66136K
QTY_1:30000
2.0054268837
QTY_2:30000
104.426306009
$chars = 'qwertyuiopasdfghjklzxcvbnm_01234567890';
function create_word(){
global $chars;
$w = '';
for ($i = 0; $i <= 100; $i++) {
$w .= $chars{rand(0, 37)};
}
return $w;
}
function create_list_of_words($count_of_words) {
$l = array();
for ($i = 0; $i < $count_of_words; $i++) {
$l[] = create_word();
}
return $l;
}
$t = microtime(true);
$l = create_list_of_words(30000);
print "\nQTY_1:".count($l)."\n";
print microtime(true) - $t;
$ls = create_list_of_words(30000);
print "\nQTY_2:".count($ls)."\n";
$t = microtime(true);
foreach ($ls as $v) {
if (in_array($v, $l)) {
true;
}
}
print "\n" . (microtime(true) - $t);
ПАМЯТЬ: 19060K
QTY1_:30000
3.97967195511
QTY2_:30000
41.5297501087
import bisect
import random
import time
chars = u'qwertyuiopasdfghjklzxcvbnm_01234567890'
def create_word():
w = ''
for n in range(101):
w += random.choice(chars)
return w
def create_list_of_words(count_of_words):
l = []
for i in xrange(count_of_words):
l.append(create_word())
return l
t = time.time()
l = create_list_of_words(30000)
print '\nQTY1_:%s' % len(l)
print time.time() - t
ls = create_list_of_words(30000)
print '\nQTY2_:%s' % len(ls)
t = time.time()
for v in ls:
if v in l:
pass
print time.time() - t
ПАМЯТЬ: 19028K
QTY1_:30000
4.41841101646
QTY2_:30000
0.0710809230804 !!!!!!!!
import bisect
import random
import time
chars = u'qwertyuiopasdfghjklzxcvbnm_01234567890'
def create_word():
w = ''
for n in range(101):
w += random.choice(chars)
return w
def create_list_of_words(count_of_words):
l = []
for i in xrange(count_of_words):
bisect.insort(l, create_word())
return l
def create_list_of_words2(count_of_words):
l = []
for i in xrange(count_of_words):
l.append(create_word())
return l
t = time.time()
l = create_list_of_words(30000)
print '\nQTY1_:%s' % len(l)
print time.time() - t
ls = create_list_of_words2(30000)
print '\nQTY2_:%s' % len(ls)
t = time.time()
for v in ls:
try:
if l[bisect.bisect_left(l, v)] == v:
pass
except:
pass
print time.time() - t
Отредактировано (Авг. 18, 2009 14:29:08)
Офлайн
NSkrypnik
через bisect можно эмулировать работу словаря. последний пример тут: http://docs.python.org/library/bisect.html как раз об этом. такчто можешь смело использовать бисект он ОЧЕНЬ БЫСТРЫЙ, за основу можешь взять мой код с бенчмарком. и чуть изменить его на основе коода из документации по питону.
Офлайн