Найти - Пользователи
Полная версия: сравнение списков - вернуть не совпадения
Начало » Python для экспертов » сравнение списков - вернуть не совпадения
1
pythonwin
есть два списка:
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
Пробовал через set - тормознее получается.
Tmr
Замечания по коду.
Функция 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
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
Небольшое дополнение, списки удобно копировать через срезы
a = [1,2,3]
b = a[:]
Tmr
Но при этом нужно помнить, что копируются не объекты, а референсы на объекты. Т.е.
>>> 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
:)
list(set(l1).difference(l))
pythonwin
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
Александр Кошелев
Такой вариант неожиданно для меня очень медленный:
filter( lambda x: x not in l, l1 )
pythonwin
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
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB