Pull to refresh

Comments 22

К счастью, в Python всегда можно избежать вложенных циклов с помощью встроенной функции product()

Отнюдь не всегда:

for a in range(3):
    for b in range(a):
        for c in range(a + b):
            print(a, b, c)

Гнать таких знаек в шею ссаными тряпками.

1. Зачастую менее очевидно, чем циклы. Реально имеет смысл, только если циклов больше 3х, или если количество циклов заранее неизвестно. Условно, перебор всех строк из N символов в заданном алфавите.
2. У моржа очень ограниченная область применения, где он не делает хуже. Смешивать два разнородных действия в одной строке - такая себе идея.
3. Для слияния двух словарей в третий имеет смысл. Для обновления существующего словаря update() всё ещё предпочтительнее.
4. Вот этот синтаксис интересен. Не знал.
5. А вот тут лучше бы сделать акцент на том, как устроены методы в питоне. Точнее, что это функции, которые явно получают self - и практически всё. Именно поэтому "hello".captialize() и str.capitalize("hello") работает одинаково, используя один и тот же код. И в ряде случаев это поведение имеет смысл использовать - не только для строк, но и для объектов других классов. Разумеется, это работает только для методов без параметров (помимо self). В противном случае всё равно придётся использовать лямбды или functools.partial().

4. Вот этот синтаксис интересен. Не знал.

Возможно вам понравится аналогичный синтаксис со словарями:

a = {"w": 5, "x": 6}
b = {"y": 7}
c = {"z": 8, **a, **b}

Почти со всем согласен, но второй пример - это же ужас, в виде мины под будущие изменния.

a, *mid, b = [1, 2, 3, 4, 5, 6]
print(a, mid, b)
# 1 [2, 3, 4, 5] 6

5 примеры вообще антипаттерн. В своё время они изгоняли map/reduce в пользу list comprehension где это возможно и добавили правило в pylint.

"hello".captialize() и str.capitalize("hello") работает одинаково, используя один и тот же код.

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

К сожалению, мы не можем напрямую поместить присвоение в функцию print().

А зачем это вообще нужно?

если вам действительно интересно - это сделано для if( ... ) \ while (..) и т.д.

#
# как было раньше
#
some_filter_res = filter_func(data)
if (some_filter_res):
  # работаем с >>>some_filter_res<<<
  ... 
# some_filter_res - пуст и не нужен


#
# а теперь с оператором моржа
#

if (some_filter_res := filter_func(data)):
  # работаем с >>>some_filter_res<<<
  ... 

я думаю для while - еще нагляднее пример :)

Я в курсе, что такое моржовый оператор. Мне было непонятно, зачем он в принте и почему автор по этому поводу так сокрушается.

То есть то, на что ругаются в C?

Подскажите, а вот на КДПВ комментарий через два слэша — это какой-то новый синтаксис в питоне?

Есть такой способ - перед тем, как уйти на перерыв, оставить явную ошибку в том месте, на котором ты остановился. Чтобы IDE всё подчёркивало красными цветами и ничего не запускалось/не компилировалось.

Возможно это тот случай

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

This user had blocked you from following them or viewing their stories.

Странно, что, еще никто не написал, что пример в "5." это ''.join((str(bit) for bit in city))

Оставлю, вдруг кому тоже пригодится.

Открыл для себя недавно красивый метод вставки переменных в строку текста из списка:

names = ['yAnG', 'MASk', 'thoMas', 'LISA']

print('{} {} {} {}'.format(*names))


print(('{} ' * len(names)).format(*names))

Мне так больше нравится, легче писать и более читабельно, если нужно вставить в большой текст:

names = ['yAnG', 'MASk', 'thoMas', 'LISA']
print(f"name1: {names[0]}, name2: {names[1]}, name3: {names[2]}, name4: {names[3]}")


OUT: name1: yAnG, name2: MASk, name3: thoMas, name4: LISA

/*DISCLAIMER: я не python разработчик, но некоторые вещи, достаточно комплексные, в том числе, приходилось и разбирать и дописывать, воспримите мой комментарий именно с этой точки зрения */

  1. for a, b, c in product(list_a, list_b, list_c): - красиво, да. Не буду брюзжать про импорт/производительность. Скорее всего внутри оно также элегантно и завернётся.

    Я узнал новую функцию.

    Как же легко будет спутать порядок переменной итератора и итерируемой сущности уже на 2+ вложенности, что Вам и статический анализатор не всегда покажет.

    Итого: уменьшили читабельность(+/-), добавили поле для ошибки(однозначно)

  2. ":=" – в целом не новшество. В предложенном контексте - для меня читабельность уменьшена, вычисляемая/простая переменная объявлена непонятно где, в лучшем случае с комплексным комментарием "а мы тут ещё это не только ... но и будем использовать дальше как ..."

  3. Красиво. Из пяти предложенных выбрал бы это самым полезным и читаемым, если бы не "|" как оператор объединения. x=1|2, 1|=2 . Воспримется спорно (смотрите первую строку комментария)

  4. Что вы гады творите, это же может и не питонщик читать)

  5. Не вижу тут "лайфхака", работа с сущностью не в лоб, через обёртку.

Полезность лично для меня - №1+№3, понял как это читать.

Полезность "лайфхаков" - давайте на всех курсах ребятам №5, через задницу это часто делают.

Первый "лайфхак" и правда заинтересовал, даже проверил

list_a = [i ** 2 for i in range(1000)]
list_b = [i ** 2 for i in range(1000)]
list_c = [i ** 2 for i in range(1000)]


def func1():
    for a in list_a:
        for b in list_b:
            for c in list_c:
                summ = a + b + c
                if summ > 2_000_000:
                    print(a, b, c)
                    return


def func2():
    for a, b, c in product(list_a, list_b, list_c):
        summ = a + b + c
        if summ > 2_000_000:
            print(a, b, c)
            return

Вывод:

4096 998001 998001
4096 998001 998001
Первый способ: 0:00:02.777251
Второй способ: 0:00:03.161027

Возможно, если циклов больше 3, то это имеет смысл (хотя слабо себе представляю такую конструкцию)

Возможно, если циклов больше 3, то это имеет смысл

Тут прелесть product в том, что он может работать не только с большим количеством списков, но и с заранее не известным количеством списков:

# Представьте, что это приходит из какого-то внешнего кода
# и мы заранее не знаем, сколько там будет списков
lists = [list_a, list_b, list_c]

for variant in product(*lists):
    # Какой-то код, который умеет работать с кортежами неизвестной длины
    print(*variant)  
Sign up to leave a comment.

Articles