Уведомления

Группа в Telegram: @pythonsu

#1 Дек. 21, 2022 21:37:05

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9852
Репутация: +  853  -
Профиль   Отправить e-mail  

Задача по шифрованию текста

indiwiduum
Есть какой-то лайфхак это обойти?
Если тебе нужен прямо .remove() внутри цикла, то for надо заменить на while. Сделать там индекс там и прочее. Тогда оно не будет ничего съедать. Ты просто поленился, сделал такой удобный for, который там всё сам перебирает, а он работает через итератор, который создаёт в фоне. А в итераторе назад ходить нельзя. Если элемент ты взял из итератора, то всё, этот элемент обратно в итератор вернуть нельзя. А в цикле while, где контроль по индексу идёт, можно всё это делать.



Офлайн

#2 Дек. 21, 2022 23:11:57

AD0DE412
Зарегистрирован: 2019-05-12
Сообщения: 1130
Репутация: +  44  -
Профиль   Отправить e-mail  

Задача по шифрованию текста

 import itertools
# extreme
text = 'aaaabbсaa'
print(''.join([''.join([i[0], str(len(list(i[1])))]) for i in itertools.groupby(text)]))
# and ultimate
print(''.join(map(lambda x: x[0] + str(len(list(x[1]))), itertools.groupby(text))))
ps py.user.next ну если вы взялись об'снять за циклы то уж разкажите про протокол next



1. пжлст, форматируйте код, это в панели создания сообщений, выделите код и нажмите что то вроде
2. чтобы вставить изображение залейте его куда нибудь (например), нажмите и вставьте ссылку на его url

есчщо

Отредактировано AD0DE412 (Дек. 22, 2022 00:01:08)

Офлайн

#3 Дек. 22, 2022 01:22:21

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9852
Репутация: +  853  -
Профиль   Отправить e-mail  

Задача по шифрованию текста

AD0DE412
то уж разкажите про протокол next
Есть глобальные функции iter() и next(). Функция iter() создаёт итератор и возвращает его. А функция next() к существующему итератору применяет операцию “взять следующий элемент” и возвращает этот элемент полученный. Когда итератор заканчивается, функция next() порождает исключение StopIteration. Оно внутри итератора возникает, переходит функции next(), а функция next() его уже наружу проводит.

Так вот цикл for эту функцию iter() вызывает неявно, а потом он так же неявно вызывает функцию next() для неявно полученного итератора. Таким образом, если ты элементы удалил какие-то впереди, то все элементы впереди сдвинутся, а цикл for на следующем шаге вызовет так же эту функцию next() и возьмёт только элемент, который там следующий по очереди по расчётам итератора. Но итератор их просто считает и знает, какой элемент следующий по счёту; он не следит, как они там удаляются без его участия. Итератор, например, их посчитал “я уже три элемента видел и вернул, а следующий элемент четвёртый”. А ты берёшь и четвёртый удаляешь, а вместо четвёртого пятый элемент ставишь. А итератор всё так же считает “я вижу четвёртый элемент, я его возвращаю, следующий будет пятый элемент”. То есть итератор не понимает, что элементы поменялись в количестве, поэтому он думает, что пятый элемент - это четвёртый, что шестой элемент - это пятый.

Дальше, что такое протокол итератора. Функции iter() и next() обращаются к методам __iter__() и __next__(). Функция iter() ищет метод __iter__() у объекта, чтобы получить из этого метода итератор. А функция next() ищет метод __next__() у итератора, чтобы получить следующий элемент или исключение StopIteration.

Любой объект, который у себя реализовал метод __iter__(), становится итерируемым - то есть способным построить итератор по запросу из функции iter() и вернуть его.
Любой объект, который у себя реализовал метод __next__(), становится итератором - то есть способным взять элемент по запросу из функции next() и вернуть его.

Пример
  
>>> text = 'abc'
>>> 
>>> text.__iter__
<method-wrapper '__iter__' of str object at 0x7facc4b00ae8>
>>> 
>>> text.__next__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute '__next__'
>>> 
>>> it = iter(text)
>>> it
<str_iterator object at 0x7facbc979710>
>>> 
>>> it.__iter__
<method-wrapper '__iter__' of str_iterator object at 0x7facbc979710>
>>> 
>>> it.__next__
<method-wrapper '__next__' of str_iterator object at 0x7facbc979710>
>>> 
>>> next(it)
'a'
>>> next(it)
'b'
>>> next(it)
'c'
>>> next(it)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> next(it)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> 
>>> itit = iter(it)
>>> itit
<str_iterator object at 0x7facbc979710>
>>>
>>> itit.__iter__
<method-wrapper '__iter__' of str_iterator object at 0x7facbc979710>
>>>
>>> itit.__next__
<method-wrapper '__next__' of str_iterator object at 0x7facbc979710>
>>> 
>>> next(itit)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>>
Как видим, у строки есть метод __iter__(), поэтому для неё можно построить итератор. При этом строка не является итератором сама по себе, потому что у неё нет метода __next__().
Когда мы построили итератор для строки, мы получили объект, у которого есть метод __next__(). Также у этого объекта есть метод __iter__(), чтобы для итератора можно было построить новый итератор. При этом, как показывает практика, обычно метод __iter__() у итератора возвращает ссылку на сам этот итератор, то есть итератор возвращает сам себя. Но это и необязательно, можно и что-то новое возвращать.

Пример
  
>>> class A:
...     def __iter__(self):
...         self.n = 0
...         return self
...     def __next__(self, default=None):
...         if self.n < 3:
...             self.n += 1
...             return 'nothing'
...         else:
...             raise StopIteration
... 
>>> a = A()
>>> a
<__main__.A object at 0x7fce57bf9748>
>>> 
>>> it = iter(a)
>>> it
<__main__.A object at 0x7fce57bf9748>
>>> 
>>> next(it)
'nothing'
>>> next(it)
'nothing'
>>> next(it)
'nothing'
>>> next(it)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 10, in __next__
StopIteration
>>> 
>>> for i in A():
...     print(i)
... 
nothing
nothing
nothing
>>>



Отредактировано py.user.next (Дек. 22, 2022 11:18:47)

Офлайн

#4 Дек. 22, 2022 07:24:22

AD0DE412
Зарегистрирован: 2019-05-12
Сообщения: 1130
Репутация: +  44  -
Профиль   Отправить e-mail  

Задача по шифрованию текста

офигенно



1. пжлст, форматируйте код, это в панели создания сообщений, выделите код и нажмите что то вроде
2. чтобы вставить изображение залейте его куда нибудь (например), нажмите и вставьте ссылку на его url

есчщо

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version