Уведомления

Группа в Telegram: @pythonsu

#1 Фев. 14, 2022 15:02:54

Shev
Зарегистрирован: 2022-01-20
Сообщения: 22
Репутация: +  0  -
Профиль   Отправить e-mail  

Задача по Python

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

 def frequency_sort(items):
    return (sorted(items, key=lambda x: items.count(x))) [::-1]

Частично решил таким образом. Прошу подсказать, каким образом выполнить условие, указанное в последнем предложении задачи. Желательно не готовое решение, а подсказка, чтобы дойти самому.

Офлайн

#2 Фев. 14, 2022 16:28:15

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

Задача по Python

Shev
Желательно не готовое решение, а подсказка, чтобы дойти самому.
.count() не надо использовать.
Да и решение твоё тоже неправильное. Видимо, ты не понял задачу и наконструировал себе в фантазиях другую задачу и стал её решать. А ведь решать надо задачу именно такую, которая поставлена, а не такую, которая удобнее выглядит. В программировании реальных программ такое происходит сплошь и рядом: тебе нужно что-то сделать и оно нифига не просто, а другие варианты не подходят или их вообще нет. Так что учись сразу решать именно те задачи, которые поставлены, а не подравнивать задачи под то, что ты умеешь делать лучше всего.

Например, в итераторе расположены числа какие-то. Вот надо сначала выдать одинаковые числа из этого итератора, которые встречаются чаще всех остальных чисел в этом итераторе. Затем надо выдать одинаковые числа из этого итератора, которые встречаются чуть реже, чем самые частые числа. И так продолжать, пока не дойдёшь до самых редких чисел.

Вот здесь .count() (очень затратная операция) не нужен. Здесь нужен один проход по итератору, в результате которого появляется словарь. Потом по этому словарю строишь новый итератор. И в новом итераторе будут все те же элементы, что и в исходном итераторе, только они будут идти в этом порядке, который указан в задаче.



Офлайн

#3 Фев. 14, 2022 17:34:26

Shev
Зарегистрирован: 2022-01-20
Сообщения: 22
Репутация: +  0  -
Профиль   Отправить e-mail  

Задача по Python

py.user.next
Видимо, ты не понял задачу и наконструировал себе в фантазиях другую задачу и стал её решать
Непонятно, откуда взялся такой вывод? Разве то, что я написал не сортирует итератор по количеству включений или решается какая то другая задача? Я новичок в программировании, но читаю русский текст вполне сносно.
С тем, что решение не правильное, спорить не буду, ибо не знаю.
За ответ Вам огромное спасибо, попробую решить через словарь, результат (если осилю) выложу на Ваш суд.

Офлайн

#4 Фев. 15, 2022 00:20:52

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

Задача по Python

Shev
Непонятно, откуда взялся такой вывод?
Это я перепутал. У тебя в задании написано так, будто итератор содержит элементы, внутри которых надо что-то искать.
Shev
то есть по количеству раз, которое они появляются в элементах
Появиться в элементе может что-то, когда он сам по себе контейнер - список, кортеж, множество. А итератор может содержать не только простые элементы, но и списки, и кортежи, и даже другие итераторы, которые могут содержать тоже что угодно.

Shev
Разве то, что я написал не сортирует итератор по количеству включений
Сортирует. Только вот функции sorted() всё равно на порядок элементов; она их переставляет как хочет, лишь бы в конце они стали отсортированы. Поэтому тебе придётся сортировать самому, чтобы порядок не нарушился. Да и получить надо итератор в итоге. Можно, конечно, съехать и сказать, что можно получить список и сделать из него итератор в любой момент, но если этот объект уже участвует в какой-то цепочке действий, то вполне вероятно, что от него ждут наличия интерфейса итератора. А у списка интерфейса итератора нет.

Так что первое - тебе нужно учесть, что речь идёт про итератор. Итератор можно прочитать только один раз. Дальше он закончится и всегда будет законченным.
  
>>> it = iter([1, 1, 1, 3, 3, 2, 2, 2])
>>> sorted(it)
[1, 1, 1, 2, 2, 2, 3, 3]
>>> sorted(it)
[]
>>> sorted(it)
[]
>>>
Вот подаётся список в твою функцию
  
>>> def frequency_sort(items):
...     return (sorted(items, key=lambda x: items.count(x))) [::-1]
... 
>>> frequency_sort([1, 1, 1, 3, 3, 2, 2, 2])
[2, 2, 2, 1, 1, 1, 3, 3]
>>>
А вот подаётся итератор в твою функцию
  
>>> def frequency_sort(items):
...     return (sorted(items, key=lambda x: items.count(x))) [::-1]
... 
>>> it = iter([1, 1, 1, 2, 2, 2, 3, 3])
>>> frequency_sort(it)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in frequency_sort
  File "<stdin>", line 2, in <lambda>
AttributeError: 'list_iterator' object has no attribute 'count'
>>>
То есть ты уже не учёл, что список и итератор - это абсолютно разные понятия. А в задаче речь именно про итератор идёт.

Второе. При возврате нужно также сохранить условие, что объект был итератором и остался итератором после сортировки.
Вот пришёл итератор, а вернулся список
  
>>> def sort_iter(it):
...     return sorted(it)
... 
>>> it = iter([1, 1, 1, 3, 3, 2, 2, 2])
>>> out = sort_iter(it)
>>> out
[1, 1, 1, 2, 2, 2, 3, 3]
>>> next(out)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'list' object is not an iterator
>>>
А вот пришёл итератор и вернулся итератор
  
>>> def sort_iter(it):
...     return iter(sorted(it))
... 
>>> it = iter([1, 1, 1, 3, 3, 2, 2, 2])
>>> out = sort_iter(it)
>>> out
<list_iterator object at 0x7fdf6a2c1780>
>>> next(out)
1
>>> next(out)
1
>>> list(out)
[1, 2, 2, 2, 3, 3]
>>>
То есть функция next() может быть применена только к итератору. И где-то кто-то может её применять уже и ждать от тебя отсортированный итератор, а ты вернёшь ему список, который вызовет исключение и падение программы, когда функция next() попытается взять элемент из этого списка.

Тебе сказали отсортировать итератор - будь добр взять его, отсортировать его и вернуть в результате такой же итератор, с которым можно дальше работать как с итератором. Это идеал.

В реальных же задачах данные могут быть вообще на миллионы и миллиарды элементов (датчик температуры с улицы Сезам посылает значения текущей температуры вообще бесконечно). Ты не сможешь хранить такие списки ни в памяти, ни где-то даже в разрозненном виде. Поэтому используются итераторы, где в памяти хранится только один элемент, а после его взятия из итератора он стирается и на его место ставится следующий элемент.



Отредактировано py.user.next (Фев. 15, 2022 00:35:46)

Офлайн

#5 Фев. 15, 2022 00:34:49

xam1816
Зарегистрирован: 2020-05-11
Сообщения: 1395
Репутация: +  124  -
Профиль   Отправить e-mail  

Задача по Python

добавить reverse=True и будет по условию

 def frequency_sort2(items):
    return sorted(items, key=lambda x: items.count(x),reverse=True)

py.user.next
Здесь нужен один проход по итератору, в результате которого появляется словарь.
со словарем понятно, интересно вот это
py.user.next
Потом по этому словарю строишь новый итератор. И в новом итераторе будут все те же элементы, что и в исходном итераторе, только они будут идти в этом порядке, который указан в задаче.
я словарь также sorted() отсортировал, а как через итератор делать?

Офлайн

#6 Фев. 15, 2022 00:40:39

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

Задача по Python

xam1816
я словарь также sorted() отсортировал
sorted() переставит элементы произвольно. А там нужно выбирать максимальный из словаря, переставлять в новый словарь (или кортеж пар), потом удалять его из словаря и дальше снова выбирать максимальный из словаря и перекидывать его в новый словарь (или кортеж пар). Когда второй словарь (или кортеж пар) будет готов полностью, можно сделать из него список всех элементов и потом этот список передать в iter() и вернуть получившийся объект, либо сделать генератор с помощью генераторного выражения, который тоже итератором является, и вернуть получившийся объект.

Так ты сохранишь порядок частот элементов, у которых частоты одинаковые. Если у тебя было
  
{2: 258, 3:8, 1: 258}
То у тебя после сортировки выведутся сначала двойки, а потом единицы, а не сначала единицы, а потом двойки. А вот функция sorted() может запросто оставить как двойки впереди, так и единицы впереди. Это зависит от положения Луны. Поэтому её и не надо применять для этой конкретной сортировки.



Отредактировано py.user.next (Фев. 15, 2022 00:51:25)

Офлайн

#7 Фев. 16, 2022 18:25:03

Shev
Зарегистрирован: 2022-01-20
Сообщения: 22
Репутация: +  0  -
Профиль   Отправить e-mail  

Задача по Python

py.user.next
А там нужно выбирать максимальный из словаря
Почему максимальный? По количеству вхождений сортировка нужна. Словарь я соорудил примерно так:
 def frequency_sort(items):
    b = {}
    for i in range(len(items)):
        b[i] = items[i]    
    return b
Но как сортировать словарь по количеству вхождений найти не могу. Причем там могут быть не только цифры но и строки. Либо есть еще мысль при создании словаря в качестве значений использовать количество вхождений:
 def frequency_sort(items):
    b = {}
    for i in range(len(items)):
        b[items[i]] = items.count(items[i])
    return b
И потом как то пытаться распаковать.

Отредактировано Shev (Фев. 16, 2022 18:26:47)

Офлайн

#8 Фев. 16, 2022 19:09:29

xam1816
Зарегистрирован: 2020-05-11
Сообщения: 1395
Репутация: +  124  -
Профиль   Отправить e-mail  

Задача по Python

 def sort_entry_count(items):
    d = {}
    for i in items:
        if i in d:
            d[i] += 1
        else:
            d[i] = 1
    sorted_d = sorted(d, key=lambda k: d[k], reverse=True)
    return (i for i in sorted_d for _ in range(d[i]))
 #
seq = iter(['a', 'a', 'b', 'b', 'b', 'c', 'd', 'e', 'e', 'e', 'e', 'e', 'e'])
res = sort_entry_count(seq)
print(res)
for i in res:
    print(i, ' ', end='')
<generator object sort_entry_count.<locals>.<genexpr> at 0x0000022F55E39B60>
e e e e e e b b b a a c d
Process finished with exit code 0

Офлайн

#9 Фев. 16, 2022 23:55:56

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

Задача по Python

Shev
Почему максимальный? По количеству вхождений сортировка нужна. Словарь я соорудил примерно так:
  
def frequency_sort(items):
    b = {}
    for i in range(len(items)):
        b[i] = items[i]    
    return b
Не, словарь вот xam1816 составил правильно.

Дальше его надо правильно отсортировать - то есть не использовать функцию sorted(), а вручную сортировать. Так как ты не можешь контролировать внутреннее устройство функции sorted(), то ты не можешь сказать ей “не переставляй местами элементы, если они одинаковые”. Она просто может на каком-то компьютере переставить их местами, а на каком-то компьютере не переставить. Это будет зависеть от версии интерпретатора, установленного на том компьютере. Код у тебя один, а запускаться он может на разных питонах, на разных компьютерах, у разных людей, в разные годы. И вот где-то будет питон с такой функцией sorted(), а где-то он будет с другой функцией sorted(). Выглядеть эти функции снаружи будут одинаково, а после сортировки в одном получившемся списке элементы будут стоять в одном порядке, а в другом получившемся списке элементы будут стоять в другом порядке.

Тут если мы почитаем внимательно, то функцию sorted() гарантируют стабильной. То есть гарантируют, что она не переставляет.

https://docs.python.org/3/library/functions.html#sorted
The built-in sorted() function is guaranteed to be stable. A sort is stable if it guarantees not to change the relative order of elements that compare equal — this is helpful for sorting in multiple passes (for example, sort by department, then by salary grade).

Добавили эту информацию в документацию только в 2014 году.
https://bugs.python.org/issue22237

Там же, если пройти дальше по истории, можно увидеть, что функция sorted() стабильна с версии Python 2.2. Но в документации информация о том, что функция гарантируется стабильной, появилась только в 2014 году.
commit 9b1e92f5a199acf20041372950b96e5896e1b634
Author: Ezio Melotti <ezio.melotti@gmail.com>
Date: Tue Oct 28 12:57:11 2014 +0100

#22237: document that sorted() is guaranteed to be stable. Initial patch by Martin Panter.
Может ли существовать версия питона, которая была выпущена кем-то до 28 October 2014, в которой функцию sorted() изменили так, что она стала нестабильной? Теоретически может быть. Вероятность мизерная. Твой код могут на ней запустить? Могут. Твой код на ней сработает и выдаст не тот порядок элементов. Вероятность этого всего ещё меньше.

Можно оставить sorted() и радоваться, что всё сделал. Но что будет, когда ты выучишь питон, понапишешь на нём программ, а потом выучишь следующий язык программирования и там тоже надо будет что-то сортировать с сохранением порядка, а аналогичная функция sort(), которая там будет, не будет стабильной, как в питоне? Таких языков дохера и больше. Функция sort() не обязана стабильной быть. Я тебе скажу, что будет. Вместо написания программы ты будешь сидеть и заполнять этот пробел в знаниях, впервые изучая возможность ручной сортировки. То есть надо будет дело делать, а ты будешь сидеть и изучать, а как же его делать. Короче, не напишешь ты программу, так как слишком много пробелов у тебя будет. Будешь маленьким мальчиком, который ждёт, когда ему на блюдечке с голубой каёмочкой принесут функцию sorted(), разжуют её для него, сделают стабильной и в ротик положат, чтобы он мог пожувать её. Ух ты! Какой молодец! Мы сегодня покакали! Достижение - уровня Эйнштейна! не меньше. То есть программистом ты не будешь, будешь вечно хуйню какую-то ждать, когда же там за тебя всё сделают. А программы будут делать другие люди - умные дяденьки с бородами и с такими вот толстыми стёклами в очках. Только и зарплату будут платить всю тоже им, а не тебе такому красивому в белой рубашечке и с причёской ёжиком, а ты у них на побегушках будешь только там бегать где-то, так как таких, как ты, мешок можно насобирать, только свистни, а таких, как они, - раз два и обчёлся, потому и зарплатой будут удерживать их в компании, а не тебя.

Так что то, что функция sorted() в питоне стабильная, - это просто везение какое-то, очередной плюсик питона и так далее. В других языках тебе так не повезёт. Так как программа у тебя учебная, значит ты учишься. А если ты учишься, учись тому, что является общим для всех языков (которые были вчера, есть сегодня и будут завтра). Тогда твои знания и навыки будут более применимы и ты сможешь и сделать то, и сделать это, и сделать пятое, и сделать десятое. Когда программу надо будет писать (а учишься ты для того, чтобы писать программы, а не для того, чтобы в пиджачке бегать по этажам), писать ты её сможешь, только обладая знаниями и навыками. А знания и навыки ты получаешь вот прямо сейчас. Потом на получение этих знаний и навыков времени не будет, потому что потом ты будешь получать следующие знания и навыки, а за ними потом следующие и так далее.



Отредактировано py.user.next (Фев. 17, 2022 00:08:28)

Офлайн

#10 Фев. 17, 2022 11:18:58

Shev
Зарегистрирован: 2022-01-20
Сообщения: 22
Репутация: +  0  -
Профиль   Отправить e-mail  

Задача по Python

py.user.next
вот xam1816 составил правильно
Мой второй вариант выдает такой же словарь, неправильно потому что там count используется?
До такого решения я самостоятельно не додумался. Я думаю тут даже не знаний не хватает, а практики.
py.user.next
пиджачке бегать по этажам
Я староват для этого). Чтобы было понимание: мне много лет, с Python пытаюсь разобраться самостоятельно (книги, интернет)

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version