Comments 79
Поставил плюс, потому что тема важная и незаслуженно недооценена. Нынешние специалисты уже не помнят проблемы, с которыми сталкивались в начале пути. А ведь эти проблемы на самом деле актуальны для всех кто начинает учиться сейчас.
На мой взгляд, объяснять циклы вместе с массивами — намного сложнее, чем все это по-отдельности. Для людей может быть проблемой осознание самой концепции массивов, индексации, отличия элемента от индекса, а тут вы еще накидываете другие концепции.
По методике преподавания циклов я уже писал статью: https://habr.com/ru/post/456500/
По методике массивов не писал, но очень хочется. Например я заметил, что в начале объяснения массивов вообще не нужно использовать циклы. Это не помогает.
Нужно сначала научить людей наполнять и выводить произвольные элементы из массива. Отдельными неповторящимися действиями, а уже потом добавлять "вот теперь мы должны заставить компьютер повторять рутину за нас".
Еще полезно рисовать трассировочные таблицы, по которым видно как данные перекладываются с места на место.
Добрый день! У Вас, вроде, неплохая статья, довольно интересно, как можно с самых азов объяснить что-то, кажущееся совсем простым, людям, не понимающим это. Правда, интересна последовательность мыслей.
Но Вы немножечко ошиблись целевой аудиторией, как по мне. На Хабре, скорее всего, нет или очень мало людей, не понимающих циклы… и маловероятно, что им будет приятно рассусоливание простейших вещей...
Если бы Вы написали статью с идеей: «Как объяснить школьнику простейшие вещи?» было бы приятнее читать, ведь так нет ощущения поучения.
Но это просто совет насчет статьи и ее преподнесения (и еще код лучше в ячейках писать, а не в скриншотах, так читабельнее).
Сама идея, которую Вы, наверное, закладывали в статью, мне нравится и интересна, но по самому Вашему докладу ее не очень просто разглядеть. Опять же, это лишь мое мнение...
Но Вы немножечко ошиблись целевой аудиторией, как по мне. На Хабре, скорее всего, нет или очень мало людей, не понимающих циклы… и маловероятно, что им будет приятно рассусоливание простейших вещей...
На хабре полно разных людей. Не надо всех под одну гребенку грести.
Почему вы не пишете такие комментарии в статьях про политику, Илона Маска или про крем от облысения?
… ну и зачем вам индекс элемента в массиве в финальном коде? А если подумать еще немного, то зачем вам append
там же, учитывая, что есть list comprehensions?
Ваше объяснение теряет самую важную деталь: результат — это исходная последовательность, для каждого элемента которой выполнена операция. Для каждого.
PS Зачем вы два раза делаете один и тот же split?
Не хочу обидеть или задеть автора, но сразу вспомнил про тех программистов, которые любят писать сложный(а может и не сложный) алгоритм в одну строчку, у которого читаемость 0. Я там такие конструкции тоже часто видел, просто для того, что бы «лишние переменные» не занимали аж целую дополнительную строчку кода. Надеюсь, автор просто сделал это, что бы читателям было легче вникнуть в суть.
Так на учебных языках, типа Паскаля, или даже псевдокода, нужно только концепции изучать, а проекты делать — переходить на промышленные языки. Не зря автогонщиков, например, учат сначала на карте ездить, а уже потом на машины посерьёзнее пересаживают.
А то начнёшь программирование с питона изучать — а тебя бах по голове пандами с однострочниками, а ты такой пока даже массив от цикла с трудом отличаешь.
Именно
Напоминает заклинание perl, но на python.
Несмотря на то, что list comprehensions юзаю и читаю часто, я с вами соглашусь, что map
и лямбды куда нагляднее. Применительно к питону
- в питоне лямбда функции имею ужасающий синтаксис:
lambda x: x
- list comprehensions быстрее, чем map
- в list comprehensions есть if, который на map'ах уже не так красиво делается. Тут нужно что-то типо
filter
celebrities.map { it.split(" ").joinToString("") { item -> item.first() + "." } }
Вообще тут ещё понятно, потому что есть чётко разделённые внешний цикл по элементам и внутренний по выделению инициалов.
А я как-то разбирал за предшественником такое:
variation_flags += [variation_flag for variation in module.variations
for variation_flag in variation]
чуть не поседел и в итоге просто заменил на более простое, топорное, но всем понятное изложение. Сейчас, кстати, понял, что я этот твистер уже не разберу, надо следующий ящик спиртного добывать ;\
А что тут непонятного (кроме порядка в каком читать — но программист на Питоне его знать должен)?
Обычная операция flatten над списком списков.
А что тут непонятного (кроме порядка в каком читать — но программист на Питоне его знать должен)?
Ну вот сейчас таки после отправки комментария посидел и показалось, что понял :)
Про порядок — таки это первый случай за весь опыт, когда такое встретилось (причём без особой надобности).
Уверен, что >90% питонщиков тоже это не поймут — ибо нужно чуть реже, чем никогда.
Уверен, что >90% питонщиков тоже это не поймут — ибо нужно чуть реже, чем никогда.
Ну, я прочитал и понял. А я даже питонщик-то ненастоящий. Ну да, я с порядком множественных for в list comprehensions один раз столкнулся в первый год, что ли, ну и запомнил. А у вас он еще и из переменных нормально выводится.
def initials(full_name: str) -> str:
name, surname = full_name.split()
return f"{name[0]}.{surname[0]}."
map(initials, celebrities)
from timeit import timeit
celebrities = ["Tom Cruise", "Linus Torvalds", "Simon Marlow"]*1000
def initials(full_name: str) -> str:
name, surname = full_name.split()
return f"{name[0]}.{surname[0]}."
def f1():
["".join(f"{item[0]}." for item in celebrity.split()) for celebrity in celebrities]
def f2():
tuple(map(initials, celebrities))
print(timeit("f1()", globals=globals(), number=100))
print(timeit("f2()", globals=globals(), number=100))
Python 3.9.1
0.161286
0.067485
1) Делаем заявление о том, что реализация №2 в 3 раза медленнее реализации №1 потому что «генераторы»
2) Чтобы это доказать переписываем реализацию №2 на свою реализацию №3
3) Доказываем что реализация №1 и №3 выполняются за одинаковое время
…
4) Справедливость восстановлена
def f0():
return [f'{name[0]}.{surname[0]}.' for name, surname
in map(str.split, celebrities)]
Мне показалось, вы интересовались скоростью решения. Надо полагать, более не интересуетесь. Ну и ладно.
А всё же согласитесь, моё решение еще и читабельно.
Привет любителям функциональщины :D
Общее у однострочников на любом языке — они write only. Вносить изменения практически невозможно. Вот, допустим, правило формирования инициалов поменялось (Джером К. Джером, например, попадется в списке). Код с традиционным циклом исправит любой школьник. Ваш вариант — тоже. Однострочник — сделать, конечно, можно, но понять, что это, сможет не каждый.
ИМХО, достаточно убрать лишнее:
celebreties = ['Tom Cruise', 'Will Smith']
shortnames = []
for person in celebreties:
person = person.split()
shortname = person[0][0] + '.' + person[1][0] + '.'
shortnames.append(shortname)
print(shortnames)
Речь в статье не о самом коротком коде, а том, что у большинства, кто берётся изучать программирование, трудности с мышлением по разным причинам. Приходится буквально учить взрослых людей ходить.
shortnames = []
for person in celebrities:
shortname = person.split()[0][0] + '.' + person.split()[1][0]
shortnames.append(shortname)
Не вижу смысла дрочиться с индексом, когда и без него всё прекрасно будет работать
shortnames=([f"""{person.split()[0][0]}.{person.split()[1][0]}.""" for person in celebrities])
но я…
shortnames = list(map(lambda person: f"""{person.split()[0][0]}.{person.split()[1][0]}.""", celebrities))
ой все…
shortnames = list(map(lambda person: "".join(map(lambda p: f"""{p[0]}.""", person.split())), celebrities))
Хоть и с болью в душе, но соглашусь). На самом деле мне обычно 80 строк хватает даже на длинные переменные и все такое, однако бывают места, как например с теми же генераторами и так далее, где в 80 ну уж никак не умещается и приходится изводится. Но вот не могу перейти на 100 или даже более. Уже и привычка и кажется слегка неудобным.
instance\
.some_method()\
.some_method()\
.some_method()
(instance
.some_method()
.some_method()
.some_method())
if a is None and\
b is None and\
c is None:
pass
if (a is None and
b is None and
c is None):
pass
А так, прошу прощения, я в этой теме не компетентен.
Спасибо всем тем парням, что пишут в одну строку. Люблю вас.
Так вот, продолжая это сравнение, приведенное здесь объяснение цикла я бы сравнил с обучением руления автомобиля через объяснение каким ими образом червячная передача передает управление от руля колесам. Оно надо это понимать осваивая азы руления?
Может действительно вспомить как мы учились рулить на велосипеде, а потом на автомобиле – повернул руль и поехал в нужную сторону.
Программирование занятие практическое. Может проще объяснить на практике пройдя по цепочке:
for item in celebrities:
print(item)
for item in celebrities:
print(item, item[0])
for item in celebrities:
print(item, item[0], item.find(' '))
for item in celebrities:
print(item, item[0], item[item.find(' ') + 1])
for item in celebrities:
print(item[0],'.',item[item.find(' ') + 1],'.')
OutList = [item[0]+'.'+item[item.find(' ') + 1]+'.' for item in celebrities]
Статья автора — пример того, как нельзя обучать. Абсолютно непонятно для новичков, какие-то странные отсылки, сложные фразы и слова. Вместо того, чтобы наглядно и понятно показать, чтобы даже бабушки и дети поняли — какие-то странные вставки в этапе 3 и 5 со строкой resident, которые вообще ни к чему, от которых у обучаемых голова пухнет от вопроса «зачем они здесь?? Что за херь? Зачем тут upper, если его нет в финальном коде?». Какие то «группы объектов», «цель написать цикл». Ага, смешно, ещё даже никто не знает, что такое цикл, и главное зачем нужен, а куча абзацев какой-то галиматьи. Очень сложно читать, уловить мысль, даже после нескольких прочтений.
«Придётся перебрать все индексы списка. Какой командой это сделать — думаю, подсказки не нужно.» — супер, мы же первый раз учим циклам, конечно подсказки не нужны. Зато мы выльем какой-то лишней воды и левых примеров, которые вообще сбивают с толку, на лишних 5 абзацев, которые вообще ни к чему.
Автор, если ты обучаешь новичков, формулируй так, чтобы понимали даже дети.
p.s. то что нельзя два раза делать один и то же person.split() — это надо говорить сразу. А то потом такие же люди идут в js и у нас фронтенд тормозит от таких деятелей, которые не догадываются о кэшировании в переменной.
Автор, преподавание это не твоё. Научись формулировать просто и понятно.
А на картинке Бейсик
Программирование очень похоже на работу классического крутого детектива из голливудских сериалов. Постоянно нужно улавливать связь между вещями, которые на первый взгляд абсолютно разрознены.
А. Так вот в чём дело...
Например, набор переменных можно представить, как конвейерную ленту с коробочками, в каждой из которых — свой товар. Сама коробочка — это и есть переменная, а надпись на неё — её имя. Внутри одной коробочки — число, внутри другой — текст, и т. д.
Дочитал абзац до конца, чтобы выяснить, что в данном примере есть конвейерная лента и куда же с такой аналогией движется память. Неудачно.
Я бы попросил автора написать на тему выборки (алгоритм выборки) из словарей в словарях, списки в словарях, словари в списках. Вот здесь очень нужны алгоритмы, так как для новичков это достаточно сложная тема, по-крайней мере для тех, кто впервые приступает к знакомству с каким бы то ни было языком программирования.
Наверняка, автор обучает и по запрашиваемой теме.
Спасибо.
Как же писать эти грёбаные циклы?