Уведомления

Группа в Telegram: @pythonsu

#1 Сен. 7, 2017 16:08:42

lkk
Зарегистрирован: 2017-09-07
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

Как работает итератор (на двух примерах)?

Всем привет!

Недавно начал изучать питон и сегодня выполняя задание по курсу на неком интернет-ресурсе столкнулся с любопытной вещью.
Задание: дан список элементов, найти в нём все что начинаются на “c”, удалить их и вывести что осталось.
Первоначально я сделал так:

 list = ['cinty','olsen','barry','cantella','cori','supreme']
for item in list:
	if item.startswith('c'): list.remove(item)
print(list)
Очевидно, что в этом коде заложен косяк - remove сместит элементы на один влево и тот элемент который должен был быть следующим займёт позицию удалённого, цикл перескочит через один элемент и задача будет невыполнена.

В итоге такой код делал всё как надо:
 list = ['cinty','olsen','barry','cantella','cori','supreme']
for item in list[::1]:
	if item.startswith('c'): list.remove(item)
print(list)

Выходит, что цикл
 for item in list:
итерирует по индексам списка, а
 for item in list[::1]:
по его элементам. Вернее я так предполагаю.

Вопрос у меня такой: может кто-то объяснить почему оно так или ткнёт ссылкой в ман/статью (можно англоязычную) где описана подоплёка такого поведения?

Отредактировано lkk (Сен. 7, 2017 16:09:30)

Офлайн

#2 Сен. 7, 2017 16:19:23

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

Как работает итератор (на двух примерах)?

lkk
Выходит, что цикл
lkk
итерирует по индексам списка, а
Именно! Дело в том, что никак иначе оно итерироваться просто не может. Список - это тот же массив, но с автоматическим выделением памяти и копированием элементов. Один черт в памяти должна быть выделена область, в которую последовательно записываются указатели на объекты-члены коллекции. Никакой магии.



Офлайн

#3 Сен. 7, 2017 17:29:21

Vintets
Зарегистрирован: 2016-07-05
Сообщения: 41
Репутация: +  6  -
Профиль   Отправить e-mail  

Как работает итератор (на двух примерах)?

lkk
Выходит, что цикл

for item in list:

итерирует по индексам списка, а

for item in list:

по его элементам. Вернее я так предполагаю.

Ты просто сделал копию списка
list[::1]
Срезами от начала до конца. Получил новый список и по нему уже пробегал циклом. А элементы удалял в первом списке.
Можно было написать просто
 list[:]
вместо
 list[::1]

Обычно если действие простое, то проще сделать так
 lst = ['cinty','olsen','barry','cantella','cori','supreme']
lst = [i for i in lst if not i.startswith('c')]
print(lst)

Или в твоём случае так
 lst = ['cinty','olsen','barry','cantella','cori','supreme']
lst = list(filter(lambda x: x.startswith('c'), lst))
print(lst)

Отредактировано Vintets (Сен. 7, 2017 17:41:12)

Офлайн

#4 Сен. 7, 2017 18:34:11

lkk
Зарегистрирован: 2017-09-07
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

Как работает итератор (на двух примерах)?

Теперь понял. Спасибо!

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version