@atsin4469

Как сделать, чтобы функция начала работать с итераторами?

Задание
Вам предстоит реализовать функцию all_unique, которая должна принимать итератор
(в т.ч. и те, которые не перезапускаемые!) и возвращать True, если элементы в итераторе
не повторяются (если элементов нет, то ничего не повторяется!). Пример работы функции:

>>> all_unique([])
True
>>> all_unique("cat")
True
>>> all_unique([1, 2, 3])
True
>>> all_unique([1, 2, 1])
False


Мое решение
def all_unique(arg):
    if not arg:
        return False
    if len(set(arg)) == len(list(arg)):
        return True
    return False


Не проходит эти тесты:
assert all_unique(iter([])), "Should work with iterators."
assert all_unique(iter([1])), (
        "Should handle non-restartable iterators too."
    )


Как сделать, чтобы проходило?
  • Вопрос задан
  • 115 просмотров
Решения вопроса 1
phaggi
@phaggi Куратор тега Python
лужу, паяю, ЭВМы починяю
Может, содержимое итератора высыпать в список и потом обрабатывать?
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
Assargin
@Assargin
Перед ответом смотрю наличие ✔ в ваших вопросах
Не надо кушать лишней памяти, и лишний раз ходить по итератору тоже.
def all_unique(iterator):
    counter = 0
    items = set()
    for item in iterator:
        items.add(item)
        counter += 1
        if len(items) != counter:
            return False
    return True

Худший случай, конечно, всегда один для данной задачи: О(N) и по памяти, и по времени. Но в лучшем случае может хватить всего лишь 2 итерации цикла и множества из 1 элемента (это когда в итераторе 2 первых элемента уже одинаковые), а в среднем будет что-нибудь типа O(N/2).
Ответ написан
@bacon
Первый же проходит, по-второму
In [1]: i = iter([1])                                                           

In [2]: set(i)                                                                  
Out[2]: {1}

In [3]: set(i)                                                                  
Out[3]: set()

In [4]: i = iter([1])                                                           

In [5]: list(i)                                                                 
Out[5]: [1]

In [6]: list(i)                                                                 
Out[6]: []

In [7]: i = iter([1])                                                           

In [8]: set(i)                                                                  
Out[8]: {1}

In [9]: list(i)                                                                 
Out[9]: []

понятней стало?
ЗЫ ну и сразу
if x == y:
    return True
return False

меняй на просто
return x == y
Ответ написан
@dmshar
Ну, например, вот так:
def all_unique(arg):
    if hasattr(arg, '__iter__'):
        arg=list(arg)
    if arg==[]:
        return True
    elif len(set(arg)) == len(list(arg)):
        return True
    return False


Корректно (кажется :-) ) проходит тесты:
all_unique([])
all_unique("cat")
all_unique([1, 2, 3])
all_unique([1, 2, 1])
all_unique([1])
all_unique(iter([]))
all_unique(iter([1]))
all_unique(iter([1, 2, 3]))
all_unique(iter([1, 2, 1]))
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы