отсортированный ключ = не относится к подспискам - PullRequest
0 голосов
/ 18 апреля 2011

Я пишу модульные тесты, один из них проверяет метод, который возвращает список, содержащий подсписки [[],[],[]], порядок подсписков не имеет значения только для количества подсписков и их значений, проблема в том, что TestCase.assertItemsEqual() устарела и не существует TestCase.assertElementsEqual() метода. Чтобы решить эту проблему, я решил отсортировать список, возвращенный из метода, и список из моего модульного теста и сравнить отсортированные версии, но проблема в том, что у списков всегда есть значение None, и сортировка вызывает ошибку:

>>> sorted( [ [None], [1,2] ] )
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() < NoneType()

На самом деле мои подсписки всегда имеют 8 значений, где одно - None, а у меня от 2 до 4 подсписков.

Итак, я написал небольшую лямбду, которая меняет None на 0, потому что порядок не имеет значения вообще, мне просто нужно убедиться, что порядок тот же:

>>> (lambda x: x if x is not None else 0)(None)
0
>>> (lambda x: x if x is not None else 0)(1)
1

Но это не работает,

>>> sorted( [ [None], [1,2] ], key = lambda x: x if x is not None else 0 )
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() < NoneType()

Сообщение об ошибке вводит меня в заблуждение, когда я думаю, что изменение NoneType на IntType будет исправлено, но я знаю, что значение x в лямбде является одним из подсписков, и поэтому лямбда просто не работает. Но я не знаю, как это исправить.

Ответы [ 2 ]

0 голосов
/ 25 апреля 2011

Я понял все сразу после того, как задал вопрос, проблема заключалась в том, что значение, переданное ключевой функции, было одним из подсписков, поэтому мне нужно было только пройтись по подсписку и изменить None на 0, как вы это сделали с normalized, вот что я получил:

# this sort a list with a sublist that has a None value in it - the None is changed to a 0 -
sort_none = lambda z: sorted( z, key= lambda x: [ 0 if y is None else y for y in x ] )
board = Board( [ 1,2,3 ,4,None,5 ,6,7,8 ] )
self.assertEqual( sort_none(board.valid_moves()),
    sort_none([
        [ 1,None,3 ,4,2,5 ,6,7,8],
        [ 1,2,3 ,None,4,5 ,6,7,8],
        [ 1,2,3 ,4,5,None ,6,7,8],
        [ 1,2,3, 4,7,5 ,6,None,8]
    ])
)

Спасибо за ваше время

0 голосов
/ 18 апреля 2011

В Python 3 гетерогенные сравнения больше не «просто работают».Я думаю, что основанием для этого изменения было то, что они возвращают потенциально неожиданные результаты.Также: мы больше не можем указывать функцию cmp для настраиваемой сортировки.Поэтому я думаю, что вы были на правильном пути, пытаясь заменить None значения.

Вы можете заменить None значения на 0 следующим образом:

L = [[None], [1, 2]]
normalized = list(list(0 if i is None else i for i in x) for x in L)
# list-comprehension alternative:
# L2 = [[0 if i is None else i for i in x] for x in L]

Тогда выможно использовать assertEquals для сравнения отсортированных списков:

expected_result = [[0], [1, 2]]
self.assertEquals(sorted(normalized), sorted(expected_result))

Редактировать:
Конечно, можно оптимизировать следующее, но если вам нужно решение для произвольных уровней вложенности, это начало:

import collections
def replace_nested(L, replacement=0):
    if None in L:
        for i,item in enumerate(L):
            if item is None:
                L[i] = replacement
    else:
        for i,S in enumerate(L):
            if isinstance(S, collections.Iterable) and not isinstance(S, str):
                replace_nested(S)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...