Уведомления

Группа в Telegram: @pythonsu

#1 Авг. 9, 2012 19:52:16

fata1ex
От:
Зарегистрирован: 2009-07-11
Сообщения: 732
Репутация: +  52  -
Профиль   Отправить e-mail  

Удалить дубликаты в списке не нарушив их порядок

Медленно и неправильно, зато воднустрочку:

>>> mylist = [1,1,2,1,4,5,6,6,8]
>>> [elem for idx, elem in enumerate(mylist) if elem not in mylist[:idx]]
[1, 2, 4, 5, 6, 8]
>>> zip(*filter(lambda (idx, elem): elem not in mylist[:idx], enumerate(mylist)))[1]
(1, 2, 4, 5, 6, 8)

Кстати, конструкция
seen = set()
filter(lambda x: x not in seen and not seen.add(x), mylist)
Заметно уступает set_compr.



Отредактировано fata1ex (Авг. 9, 2012 20:26:13)

Офлайн

#2 Авг. 9, 2012 20:10:49

odnochlen
Зарегистрирован: 2012-06-28
Сообщения: 794
Репутация: +  14  -
Профиль   Отправить e-mail  

Удалить дубликаты в списке не нарушив их порядок

fata1ex
зато воднустрочку:
Перлотрах?

Офлайн

#3 Авг. 10, 2012 03:28:15

EBFE
Зарегистрирован: 2012-07-03
Сообщения: 99
Репутация: +  20  -
Профиль   Отправить e-mail  

Удалить дубликаты в списке не нарушив их порядок

tfox
Здесь черт ногу поломает
Ну можно и так:
def unique(_):
    __ = set()
    ___ = __.add
    return [_ for _ in _ if _ not in __ and not ___ (_)]

def unique2(_, __ = type({( )})):
    __ = type("(_._)", (__,),{'_':__.add}) ()
    return [_ for _ in _ if _ not in __ and not __._(_)]

def unique3(_, __ = type({( )})):
    __ = type("""
                      .-=-.          .--.
          __        .'     '.       /  " )
  _     .'  '.     /   .-.   \     /  .-'\
 ( \   / .-.  \   /   /   \   \   /  /    ^
  \ `-` /   \  `-'   /     \   `-`  /
jgs`-.-`     '.____.'       `.____.'""", (__,),
 {'_' : __.__dict__[filter(lambda _: '_' not in _,
                    sorted(__.__dict__))[::-1].pop()]})( {( )} )
    return [_ for _ in _ if _ not in __ and not __._(_)]


odnochlen
А не нарушает ли это концепцию ФП (функция получается грязной, результат для одного элемента зависит от другого)?.
Конечно нарушает
Но грязно в этом случае имхо скорее зависимость от logical expression evaluation order / ассоциативности. Обычно ожидается что “expr1 or/and/… expr2” <=> “expr2 or/and/… expr1” .
A тут “подлянка”:
if not collect.add(e) and e not in collect" 
будет выдавать совершенно другой результат.

Офлайн

#4 Авг. 10, 2012 15:21:28

tfox
Зарегистрирован: 2012-04-13
Сообщения: 55
Репутация: +  0  -
Профиль   Отправить e-mail  

Удалить дубликаты в списке не нарушив их порядок

def unique(lst):
    [b]seen = set()[/b]
    result = []
    for x in lst:
        if x in seen:
            continue
        seen.add(x)
        result.append(x)
    return result

А зачем здесь использовать множество?
Все прекрасно работает и без множества.

def unique(lst):
    result = []
    for x in lst:
        if x in result:
            continue
        result.append(x)
    return result

Офлайн

#5 Авг. 10, 2012 15:31:32

fata1ex
От:
Зарегистрирован: 2009-07-11
Сообщения: 732
Репутация: +  52  -
Профиль   Отправить e-mail  

Удалить дубликаты в списке не нарушив их порядок

Программисту хорошо бы знать базовые структуры данных и понимать, как они работают. Поговаривают, что с этого надо начинать изучать программирование.



Отредактировано fata1ex (Авг. 10, 2012 15:31:54)

Офлайн

#6 Авг. 10, 2012 15:47:20

tfox
Зарегистрирован: 2012-04-13
Сообщения: 55
Репутация: +  0  -
Профиль   Отправить e-mail  

Удалить дубликаты в списке не нарушив их порядок

Вы правы.
reclosedev, использовал множество так там элементы уникальны. В множестве дубликатов не будет. Хотя оператор in прекрасно работает и со списками. Думаю, что потребность использовать множество здесь отпадает.

Офлайн

#7 Авг. 10, 2012 15:55:03

fata1ex
От:
Зарегистрирован: 2009-07-11
Сообщения: 732
Репутация: +  52  -
Профиль   Отправить e-mail  

Удалить дубликаты в списке не нарушив их порядок

1000 21
bench_set_loop 0.618780851364
bench_list_loop 1.7107770443
10000 21
bench_set_loop 5.74140501022
bench_list_loop 17.0790119171

Вы неправильно думаете. Вместо: “О, кажется, и так работает, значит они ошиблись, а я и так всё знаю”, надо было подумать: “Зачем-то же он написал именно множество, наверно, неспроста. Зачем-то же мне сказали о структурах данных, наверно, не просто так. А что я изменил в своём коде, а как это могло повлиять на работу программы, а чем отличается список от множества?”.



Отредактировано fata1ex (Авг. 10, 2012 16:00:33)

Офлайн

#8 Авг. 10, 2012 15:55:34

EBFE
Зарегистрирован: 2012-07-03
Сообщения: 99
Репутация: +  20  -
Профиль   Отправить e-mail  

Удалить дубликаты в списке не нарушив их порядок

tfox
А зачем здесь использовать множество?
Все прекрасно работает и без множества.
Множества в Pythone реализованы через Хеш-таблицу.
Т.е поиск, вставка элементов в среднем выполняются за время O(1).
Поиск в списке выполняется за время O(n) n = количество элементов в списке.
Получается, вариант с множеством выполняется за ~ O(n), со списком за O(n^2).
def bench_unique_set(lst):
    seen = set()
    result = []
    for x in lst:
        if x in seen:
            continue
        seen.add(x)
        result.append(x)
    return result
def bench_unique_list(lst):
    result = []
    for x in lst:
        if x in result:
            continue
        result.append(x)
    return result
import timeit
import random
for elem in (10000, 30000, 50000, 100000):
    mylist = [random.randint(0, elem) for i in range(elem)]
    print elem, len(set(mylist))
    for name, func in [(k,v) for k,v in globals().items()
                       if k.startswith('bench')]:
        print " %-20s %s" % (name, timeit.timeit(
              lambda: func(mylist),number = 1))
10000 6328
 bench_unique_set     0.00341678590387
 bench_unique_list    0.853494333394
30000 19064
 bench_unique_set     0.00928298693915
 bench_unique_list    7.69523085824
50000 31700
 bench_unique_set     0.0212902408726
 bench_unique_list    21.3993917074
100000 63186
 bench_unique_set     0.047203690252
 bench_unique_list    87.1938787334

Отредактировано EBFE (Авг. 10, 2012 16:00:24)

Офлайн

#9 Авг. 10, 2012 15:59:52

tfox
Зарегистрирован: 2012-04-13
Сообщения: 55
Репутация: +  0  -
Профиль   Отправить e-mail  

Удалить дубликаты в списке не нарушив их порядок

А, понятно. Поскольку массивы данных у меня маленькие то разницы никакой не почувствовал.

Офлайн

#10 Авг. 11, 2012 00:42:14

odnochlen
Зарегистрирован: 2012-06-28
Сообщения: 794
Репутация: +  14  -
Профиль   Отправить e-mail  

Удалить дубликаты в списке не нарушив их порядок

Зато вот тут человек прочувствовал ее в полной мере.

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version