pythonwin
Март 21, 2007 08:55:06
есть два списка:
l=["%s"%e for e in xrange(10)]
l1=['10']+l+['-1\n']
и есть функции которые возвращают список элементов второго списка, которых нет в первом:
def a1():
l_1=l
for e in l:
if e in l1:
l_1.remove(e)
return l_1
def a2():
return [e for e in l1 if not(e in l)]
a3 = lambda l,l1: [e for e in l1 if not(e in l)]
def a4():
l_1 = l1
[l_1.remove(e) for e in l_1 if not(e in l)]
return l_1
результаты
python -m timeit “import two_list_1; two_list_1.a1()”
100000 loops, best of 3: 3.19 usec per loop
python -m timeit “import two_list_1; two_list_1.a2()”
100000 loops, best of 3: 10.7 usec per loop
python -m timeit “import two_list_1; two_list_1.a3(two_list_1.l, two_list_1.l1)”
100000 loops, best of 3: 10.2 usec per loop
python -m timeit “import two_list_1; two_list_1.a4()”
100000 loops, best of 3: 8.32 usec per loop
какие есть способы более быстрого сравнения списков?
Striver
Март 21, 2007 12:34:56
Пробовал через set - тормознее получается.
Tmr
Март 21, 2007 13:04:01
Замечания по коду.
Функция a1() модифицирует список l во время итераций в цикле. В результате результат неверный
Вместо l_1=l нужно делать
import copy
l_1 = copy.copy(l) # объекты по ссылке в списке не копируются, копируются ссылки
# или
l_1 = copy.deepcopy(l) # l копируется полностью
Так же нужно поменять местами в коде a1() l и l1 т.е.
def a1():
l_1 = copy.copy(l1)
for e in l1:
if e in l:
l_1.remove(e)
return l_1
В a4() дела обстоят аналогично.
Предлагаю для тестирования новый вариант:
import copy
def a1():
l_1 = copy.copy(l1)
for e in l1:
if e in l:
l_1.remove(e)
return l_1
def a2():
return
a3 = lambda l,l1:
def a4():
l_1 = copy.copy(l1)
return l_1
def simple_test():
l=
l1=+l+
res=
print a1() == res
print a2() == res
print a3(l, l1) == res
print a4() == res
pythonwin
Март 21, 2007 13:14:37
python -m timeit “import two_list_2; two_list_2.a1()”
10000 loops, best of 3: 22.2 usec per loop
python -m timeit “import two_list_2; two_list_2.a2()”
100000 loops, best of 3: 10.3 usec per loop
python -m timeit “import two_list_2; two_list_2.a3(two_list_2.l,two_list_2.l1)”
100000 loops, best of 3: 10.6 usec per loop
python -m timeit “import two_list_2; two_list_2.a4()”
10000 loops, best of 3: 24 usec per loop
сделал несколько тестов - самый пока самая быстрая a2()
xonix
Март 21, 2007 13:33:13
Небольшое дополнение, списки удобно копировать через срезы
Tmr
Март 21, 2007 14:22:42
Но при этом нужно помнить, что копируются не объекты, а референсы на объекты. Т.е.
>>> a = ['aaa', ]
>>> b = a
>>> print ‘a = ’, a, ‘ b = ’, b
a = ['aaa', ] b = ['aaa', ]
>>> b = ‘bbb’
>>> print ‘a = ’, a, ‘ b = ’, b
a = ['aaa', ] b = ['bbb', ]
>>> b = “b is share it!”
>>> print ‘a = ’, a, ‘ b = ’, b
a = ['aaa', ] b = ['bbb', ]
ofigetitelno
Март 21, 2007 15:27:45
:)
list(set(l1).difference(l))
Александр Кошелев
Март 22, 2007 10:49:32
Такой вариант неожиданно для меня очень медленный:
filter( lambda x: x not in l, l1 )