Уведомления

Группа в Telegram: @pythonsu

#1 Март 21, 2007 08:55:06

pythonwin
От:
Зарегистрирован: 2006-07-18
Сообщения: 1294
Репутация: +  0  -
Профиль   Отправить e-mail  

сравнение списков - вернуть не совпадения

есть два списка:

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
какие есть способы более быстрого сравнения списков?



Офлайн

#2 Март 21, 2007 12:34:56

Striver
От:
Зарегистрирован: 2006-10-26
Сообщения: 247
Репутация: +  22  -
Профиль   Отправить e-mail  

сравнение списков - вернуть не совпадения

Пробовал через set - тормознее получается.



Офлайн

#3 Март 21, 2007 13:04:01

Tmr
От:
Зарегистрирован: 2007-03-12
Сообщения: 14
Репутация: +  0  -
Профиль   Отправить e-mail  

сравнение списков - вернуть не совпадения

Замечания по коду.
Функция 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



Офлайн

#4 Март 21, 2007 13:14:37

pythonwin
От:
Зарегистрирован: 2006-07-18
Сообщения: 1294
Репутация: +  0  -
Профиль   Отправить e-mail  

сравнение списков - вернуть не совпадения

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()



Отредактировано (Март 21, 2007 13:18:11)

Офлайн

#5 Март 21, 2007 13:33:13

xonix
От:
Зарегистрирован: 2006-12-31
Сообщения: 38
Репутация: +  0  -
Профиль   Отправить e-mail  

сравнение списков - вернуть не совпадения

Небольшое дополнение, списки удобно копировать через срезы

a = [1,2,3]
b = a[:]



Офлайн

#6 Март 21, 2007 14:22:42

Tmr
От:
Зарегистрирован: 2007-03-12
Сообщения: 14
Репутация: +  0  -
Профиль   Отправить e-mail  

сравнение списков - вернуть не совпадения

Но при этом нужно помнить, что копируются не объекты, а референсы на объекты. Т.е.
>>> 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', ]



Офлайн

#7 Март 21, 2007 15:27:45

ofigetitelno
От:
Зарегистрирован: 2006-08-01
Сообщения: 136
Репутация: +  0  -
Профиль   Отправить e-mail  

сравнение списков - вернуть не совпадения

:)
list(set(l1).difference(l))



Офлайн

#8 Март 22, 2007 09:24:57

pythonwin
От:
Зарегистрирован: 2006-07-18
Сообщения: 1294
Репутация: +  0  -
Профиль   Отправить e-mail  

сравнение списков - вернуть не совпадения

l=["%s"%e for e in xrange(10)]
l1=['10']+l+['-1\n']
 
def a1():
    l_1 = l1[:]
    for e in l1:
        if e in l:
            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 l1 if (e in l)]
    return l_1
#
def a5():
    return list(set(l1).difference(l))
 
def simple_test():
    l=["%s"%e for e in xrange(10)]
    l1=['10']+l+['-1\n']
    res=['10','-1\n']    
    print a1() == res
    print a2() == res
    print a3(l, l1) == res
    print a4() == res

python -m timeit “import two_list_3; two_list_3.a5()”
100000 loops, best of 3: 11.6 usec per loop



Офлайн

#9 Март 22, 2007 10:49:32

Александр Кошелев
От: Москва
Зарегистрирован: 2007-02-03
Сообщения: 1724
Репутация: +  2  -
Профиль   Отправить e-mail  

сравнение списков - вернуть не совпадения

Такой вариант неожиданно для меня очень медленный:

filter( lambda x: x not in l, l1 )



Офлайн

#10 Март 22, 2007 11:05:03

pythonwin
От:
Зарегистрирован: 2006-07-18
Сообщения: 1294
Репутация: +  0  -
Профиль   Отправить e-mail  

сравнение списков - вернуть не совпадения

def a6():
    return filter( lambda x: x not in l, l1 )

python -m timeit “import two_list_3; two_list_3.a6()”
100000 loops, best of 3: 16.1 usec per loop



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version