Уведомления

Группа в Telegram: @pythonsu

#1 Авг. 29, 2012 09:51:18

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

Удаление элементов списка

Собственно есть 1 проблема, которую вроде бы можно и решить другим путем, но все равно интересен вопрос - почему, казалось бы логичная операция не приводит к желаемому эффекту?

Задача, есть список вида -

a = [1,2,3,4,4,4]
, нужно оставить в списке только максимальные числа, т.е. привести его к виду -
a = [4,4,4]

В чем проблема?

for i in a:
if i != max(a): a.remove(i)
# Выведет [2,4,4,4]

Удаляются только числа 1 и 3, двойку он упорно не хочет удалять с первого раза, однако при второй попытке воспроизвести аналогичный код удаляется и двойка, и остается желаемый результат -
Почему так происходит?

Собственно решение которое я нашел - это использование встроенной функции filter():

def delet(elem):
if elem != max(a): return False
return True

filter(delet, a) # Всегда возвращает нужный результат с первого раза

Вроде бы действия аналогичны, только первое делается напрямую, а второе через функцию, парадокс …



Отредактировано Mozart (Авг. 29, 2012 09:53:17)

Офлайн

#2 Авг. 29, 2012 10:08:09

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Удаление элементов списка

попробуй так

a=[1,2,3,4,4,4]
a=[x for x in a if x==max(a)]



Офлайн

#3 Авг. 29, 2012 10:12:22

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

Удаление элементов списка

FishHook
попробуй так
a=[1,2,3,4,4,4]
a=[x for x in a if x==max(a)]
и легким движением руки получим на ровном месте квадратичную сложность



Вот здесь один из первых отарков съел лаборанта. Это был такой умный отарк, что понимал даже теорию относительности. Он разговаривал с лаборантом, а потом бросился на него и загрыз…

Офлайн

#4 Авг. 29, 2012 10:14:34

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Удаление элементов списка

Mozart
Вроде бы действия аналогичны, только первое делается напрямую, а второе через функцию, парадокс …
Нет действия не аналогичны. Во втором случае ты собираешь новый список, а в первом делаешь цикл по списку и в цикле же список же изменяешь. На первом проходе ты удалил первый элемент, первым элементом у тебя стал второй (в твоем примере 2). На следующей иттерации в цикл попадает второй элемент, но второй элемент у тебя теперь 3, т.е. двойка не обработается.



Офлайн

#5 Авг. 29, 2012 10:55:47

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

Удаление элементов списка

Т.е. если нужен результат подобный моему лучше всего создавать новый список, либо придется загонять цикл еще в 1 цикл с range что бы повторно пройтись по всем пропущенным элементам, понял в общем, спасибо :)



Офлайн

#6 Авг. 29, 2012 11:16:23

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Удаление элементов списка

Mozart
Т.е. если нужен результат подобный моему лучше всего создавать новый список, либо придется загонять цикл еще в 1 цикл с range что бы повторно пройтись по всем пропущенным элементам, понял в общем, спасибо

В твоем случае циклы в явном виде вообще не нужны.
Просто по-другому посмотри на задачу
a = [1,2,3,4,5,6,6,6,6]
m=max(a)
a=[m]*a.count(m)
print a



Офлайн

#7 Авг. 29, 2012 11:43:23

Singularity
Зарегистрирован: 2011-07-28
Сообщения: 1387
Репутация: +  75  -
Профиль   Отправить e-mail  

Удаление элементов списка

for i in a[:]:
	if i != max(a): a.remove(i)
# Выведет [4,4,4]
так будет работать

Офлайн

#8 Авг. 29, 2012 12:37:30

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

Удаление элементов списка

Всем спасибо за помощь, все понятно, итоге сделал вообще вот так:

a = [1,2,3,4,4,4]
(lambda x: [x for x in a if x == max(a)]) (a)
# [4,4,4]



Офлайн

#9 Авг. 29, 2012 12:50:23

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

Удаление элементов списка

Mozart
Всем спасибо за помощь, все понятно, итоге сделал вообще вот так:

a = [1,2,3,4,4,4]
(lambda x: [x for x in a if x == max(a)]) (a)
# [4,4,4]

Пойду повешусь…



Вот здесь один из первых отарков съел лаборанта. Это был такой умный отарк, что понимал даже теорию относительности. Он разговаривал с лаборантом, а потом бросился на него и загрыз…

Офлайн

#10 Авг. 29, 2012 12:54:40

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

Удаление элементов списка

Mozart, сделали ужасно.

import random
import timeit
  
from functools import partial
from itertools import repeat
from operator import ne
 
  
def bench_remax(array):
    return [elem for elem in array if elem == max(array)]
  
def bench_count(array):
    m = max(array)
    return [m] * array.count(m)
 
def bench_lambda(a):
    # Оставлю как есть, пожалуй :)
    return (lambda x: [x for x in a if x == max(a)]) (a)
 
def bench_filter(array):
    m = max(array)
    return filter(partial(ne, m), array)
 
def bench_repeat(array):
    m = max(array)
    return list(repeat(m, array.count(m)))
  
N = 10
for elem_count in (100, 1000, 10000):
    array = [random.randint(0, elem_count) for i in range(elem_count)]
     
    print '\n # {0}\n'.format(elem_count)
     
    for name, func in [(k, v) for k, v in globals().items()
                                         if k.startswith('bench')]:
        print "  %-20s %s" % (name, timeit.timeit(lambda: func(array), number=N))

 # 100

bench_lambda 0.00209403038025
bench_repeat 6.19888305664e-05
bench_filter 0.000113037567139
bench_count 4.10079956055e-05
bench_remax 0.00198006629944

# 1000

bench_lambda 0.182899951935
bench_count 0.000312089920044
bench_filter 0.000803776931763
bench_remax 0.179729938507
bench_repeat 0.000330024429321

# 10000

bench_lambda 18.3123149872
bench_count 0.00310397148132
bench_filter 0.00747291946411
bench_remax 17.8990738392
bench_repeat 0.00298094749451

Самый адекватный вариант по скорости и по логике “count”.

>>> from __future__ import print_function
>>> (lambda x: print(x))('Hello world!')
Hello world!
>>> (lambda x: (lambda x: print(x))(x))('Hello world!')
Hello world!



Отредактировано fata1ex (Авг. 29, 2012 13:44:43)

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version