Дан фрагмент Python: def unique_items(lst): return list(set(lst)) — объясните, почему такой код может нарушать порядок элементов, напишите юнит‑тесты, демонстрирующие проблему, и предложите исправленную реализацию

9 Фев в 11:00
11 +1
0
Ответы
1
Коротко — почему: `set` не сохраняет порядок элементов; `list(set(lst))` удаляет дубликаты, но итерирует элементы в произвольном (зависящем от хешей и реализации) порядке, поэтому исходный порядок нарушается.
Юнит‑тесты (unittest), которые проверяют сохранение первого вхождения и продемонстрируют проблему при использовании `list(set(...))`:
```python
import unittest
# исходная проблемная реализация
def unique_items_bad(lst):
return list(set(lst))
class TestUniqueItems(unittest.TestCase):
def test_preserve_order_strings(self):
lst = ['a', 'b', 'a', 'c', 'b']
# ожидаем первый порядок появления: 'a','b','c'
self.assertEqual(unique_items_bad(lst), ['a', 'b', 'c'])
def test_preserve_order_numbers(self):
lst = [3, 1, 2, 3, 2, 1]
self.assertEqual(unique_items_bad(lst), [3, 1, 2])
if __name__ == '__main__':
unittest.main()
```
Эти тесты проверяют семантику «оставить только первые вхождения в исходном порядке». При запуске с проблемной реализацией тесты, как правило, падают (потому что `unique_items_bad` может вернуть элементы в другом порядке).
Правильные реализации (рекомендуемые):
1) Простая и быстрая (Python 3.7+, порядок словарей гарантирован по спецификации):
```python
def unique_items(lst):
return list(dict.fromkeys(lst))
```
2) Надёжная реализация, которая также корректно работает с не‑хешируемыми элементами (например, списками):
```python
def unique_items(lst):
seen = set()
result = []
for x in lst:
try:
if x not in seen:
seen.add(x)
result.append(x)
except TypeError:
# x не-хешируемый — сравниваем полноценно по равенству среди уже добавленных
if x not in result:
result.append(x)
return result
```
Пояснения:
- `dict.fromkeys` сохраняет порядок первых ключей и кратко решает задачу для хешируемых объектов.
- Вторая реализация даёт корректное поведение и когда элементы не‑хешируемы (добавляет в результат только при отсутствии равного элемента).
9 Фев в 11:08
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир