Найти - Пользователи
Полная версия: Удаление элементов списка
Начало » Python для новичков » Удаление элементов списка
1 2
Mozart
Собственно есть 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) # Всегда возвращает нужный результат с первого раза

Вроде бы действия аналогичны, только первое делается напрямую, а второе через функцию, парадокс …
FishHook
попробуй так
a=[1,2,3,4,4,4]
a=[x for x in a if x==max(a)]
PooH
FishHook
попробуй так
a=[1,2,3,4,4,4]
a=[x for x in a if x==max(a)]
и легким движением руки получим на ровном месте квадратичную сложность
FishHook
Mozart
Вроде бы действия аналогичны, только первое делается напрямую, а второе через функцию, парадокс …
Нет действия не аналогичны. Во втором случае ты собираешь новый список, а в первом делаешь цикл по списку и в цикле же список же изменяешь. На первом проходе ты удалил первый элемент, первым элементом у тебя стал второй (в твоем примере 2). На следующей иттерации в цикл попадает второй элемент, но второй элемент у тебя теперь 3, т.е. двойка не обработается.
Mozart
Т.е. если нужен результат подобный моему лучше всего создавать новый список, либо придется загонять цикл еще в 1 цикл с range что бы повторно пройтись по всем пропущенным элементам, понял в общем, спасибо :)
FishHook
Mozart
Т.е. если нужен результат подобный моему лучше всего создавать новый список, либо придется загонять цикл еще в 1 цикл с range что бы повторно пройтись по всем пропущенным элементам, понял в общем, спасибо

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

a = [1,2,3,4,4,4]
(lambda x: [x for x in a if x == max(a)]) (a)
# [4,4,4]
PooH
Mozart
Всем спасибо за помощь, все понятно, итоге сделал вообще вот так:

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

Пойду повешусь…
fata1ex
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!
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