LINUX.ORG.RU

Как часто используете next в python?

 , ,


0

3

В отличии от бэйсика next не нужен при каждом цикле в python

При этом иногда next наряду с set|any|all позволяет обойтись без break|continue соответственно

Отсюда и зондаж: когда вы пользуетесь(если вообще)next?

Когда это удобно и не нарушает читаемость кода

router ★★★★★
()

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

annulen ★★★★★
()

Когда это удобно и не нарушает читаемость кода

anonymous
()

Спасибо, узнал про оператор next в Python )))

И про set/any/all надо бы почитать

Обычно использую только break/continue

I-Love-Microsoft ★★★★★
()

Всегда, когда нужно проитерироваться по списку, пропустив первый элемент, например. Не my_list[1:] же делать.

anonymous
()

Вообще в питоне объект итератора, создаваемый iter - тоже встречается довольно редко, что приводит к тому что чтоб где-то использовать next - надо ещё и явно создать объект итератора на основе sequence

В очень редких случаях использую для взятия первого элемента из коллекции s неизвестной и возоможно нулевой длины

first_or_none = next(iter(s), None)

Читабельность этого под большим вопросом, часто вместо этого делаю

seq_start = list(s)[:1]

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

Так что на мой взгляд - next годится только для написания продвинутых утилитных функций в стиле more-itertools, вне такого библиотечного кода применений почти не вижу.

Что имелось ввиду под избежать break/continue - вообще не понял. Имеется ввиду работа с явно созданным объектом итератора в цикле while вместо for __ in коллекция?

GPFault ★★★
()
Ответ на: комментарий от GPFault

Вообще в питоне объект итератора, создаваемый iter - тоже встречается довольно редко

Да, их обычно с помощью itertools создают

annulen ★★★★★
()
Ответ на: комментарий от anonymous

А если чуть серьёзнее, то когда мы учились, были, например, шутки про то, как поделить на разыменованный указатель (/*p...) и т.п.
А тут целая тема: «Нравится ли вам оператор for»

anonymous
()

Чаще всего с generator expressions, например тут поиск по dict/list:

@staticmethod
def identify(serial: str) -> Product | None:
    return next((p for (s, p) in SERIAL_MAP.items() if serial.startswith(s)), None)

next((i[1] for i in parts if i[0] == "model"), None)

И чё это сразу «если вообще пользуетесь»?

Никогда что ли однострочники по приколу не писали? Я имею в виду забористые, типа

exec(__import__('zlib').decompress(__import__('base64').b64decode('{encoded}')).decode('utf8'))

Правда тут даже лямбд нет, помню были примеры ещё круче.

Когда это удобно и не нарушает читаемость кода

Пацаны, дух старой школы живёт только в говнокоде…

entrance
()
Последнее исправление: entrance (всего исправлений: 1)

В чом цель опроса? Реализация итераторов в питоне ублюдочна, так и так, но именно на ней построены все штатные циклы. По итогу все эти констракции являются обёртками над (*Py_TYPE(it)->tp_iternext)(it).

На самом деле сама реализация байткода FOR_ITER говорит о том, насколько это убогая штука:
https://github.com/python/cpython/blob/main/Python/ceval.c#L3705-L3716
Они сделали специальную обработку для индексирования по массивам с целочисленным индексом, потому что цирк с конями и клоунами для простой итерации реально не нужен.
Забавно то, что внутри CPython есть разница между «итератор вернул None» ( Py_NewRef(Py_None) ) и «итерирование закончилось» ( PyErr_SetNone(PyExc_StopIteration) ) — но в языке это разделение недоступно. И оно немудрено, потому что язык создавался во времена, когда обрабатывать ошибки было немодно. А вы думаете почему люди ноют про стектрейсы на два экрана?

byko3y ★★★★★
()
Ответ на: комментарий от byko3y

А что там не ублюдочно?
Например:

s = 1
def f():
   l = lambda: s
   # ...
   return l

Что захватится? Внешняя s, COPY_FREE_VARS и все дела.
ОК. А тут что захватится?

s = 1
def f():
   l = lambda: s
   # ...
   s = 2
   return l

Локальная s. Тихий и спокойный MAKE_CELL, Вроде норм, без nonlocal же. Однако s была перекрыта черте где ниже по контексту. Где мои эксепшны о факте перекрытия имени после его использования, Питон?

anonymous
()
Ответ на: комментарий от anonymous

Не, конечно лучше всегда для итерации делать my_list[1:], т.к. однородность кода важна. А обычно когда в списке надо первый элемент пропускать, то окажется что и второй надо иногда или последний. А так однороднее будет. Другой вопрос в производительности - там у next есть плюсы. С другой стороны слайс это множество элементов а next-ом их по штуке обрабатывать (что может оказаться и медленнее, смотря как обрабатывать). Если ты попутал извлечение первого элемента, как my_list[:1] то такое имеет право на жизнь, но не более того.

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 2)
Ответ на: комментарий от anonymous

Что захватится?

Хах, поведение глобальных переменных меняли в разных версиях питона. То есть, твой код захватит глобальную s на двойке и локальную на тройке. Прикол с «опять вася испортил глобальную переменную, причём, его-то код работает и тесты проходят, потому что он для себя значение правильное установил» настолько всех достало, что они наконец решили это исправить.

Я давно грю, что питон — это фрактал бездарной архитектуры или её отсутствия, «один посрал — второй поел».

byko3y ★★★★★
()
Ответ на: комментарий от byko3y

твой код захватит глобальную s на двойке и локальную на тройке

Ну да, я про тройку. We don’t talk about Vista Win8 Python 2

Прикол с «опять вася испортил глобальную переменную

по сути остался, хоть и не такой явный

наконец решили это исправить

Густо присыпали солью и перцем. Но от большего количества специй дерьмо в пищу не превратится.

anonymous
()

Очень редко реально нужен, т.к. в целом iterables идиоматичнее обходить без него. Но, вот, например, конкретный кейс, когда удобно было использовать.

with open(filename, 'r') as f:
    rdr = csv.reader(f)
    hdr = next(rdr) # тут мне нужен был только заголовок
    p = Parser(hdr) # <- для вот этого друга 
    with open(filename+'.result.csv', 'w') as f2:
        wrt = csv.writer(f2)
        wrt.writerow(hdr)
        for i, row in enumerate(rdr):
            pass
paddlewan
()

Редко, очень. Долго пытался вспомнить, потом увидел кусок кода в одном из комментов. Обычно только если логика настолько упорота что приходится вручную резать данные

upcFrost ★★★★★
()
  • Markdown
Пустая строка (два раза Enter) начинает новый абзац. Знак '>' в начале абзаца выделяет абзац курсивом цитирования.
Внимание: прочитайте описание разметки Markdown.
Используйте Ctrl-Enter для размещения комментария