Лучший способ утверждать тип данных всех значений в словаре Python - PullRequest
1 голос
/ 01 мая 2020

Я создаю модульный тест, который проверяет / проверяет, все ли значения в словаре имеют одинаковый тип данных: float.

Python версия 3.7.4

Предположим, у меня есть четыре разных словаря как таковые:

dictionary1: dict = {
    "key 1": 1.0,
}

dictionary2: dict = {
    "key 1": "1.0",
}

dictionary3: dict = {
    "key 1": 1.0,
    "key 2": 2.0,
    "key 3": 3.0
}

dictionary4: dict = {
    "key 1": "1",
    "key 2": "2",
    "key 3": 3
}

И пример модульного теста как таковой:

class AssertTypeUnitTest(unittest.TestCase):

    def test_value_types(self):
        dictionary: dict = dictionary
        self.assertTrue(len(list(map(type, (dictionary[key] for key in dictionary)))) is 1 and
                            list(map(type, (dictionary[key] for key in dictionary)))[0] is float)


if __name__ == "__main__":
    unittest.main()

Ожидаемым результатом будет то, что он выдаст AssertionError, если в словаре есть одно значение, отличное от float, то есть это будет сделано для dictionary2, но не для dictionary1.

Теперь, когда тест работает для 1 пары ключ-значение , как бы я сделал это для нескольких пар ключ-значение в таких случаях, как dictionary3 и dictionary4, не добавляя еще один для l oop?

т.е.

for type in list(map(type, (dictionary[key] for key in dictionary))):
    self.assertTrue(type is float)

Спасибо!

Ответы [ 2 ]

0 голосов
/ 01 мая 2020

Давайте разберем написанное вами утверждение, чтобы понять, что оно на самом деле делает.

self.assertTrue(
    len(list(map(type, (dictionary[key] for key in dictionary)))) is 1  #
    and  #
    list(map(type, (dictionary[key] for key in dictionary)))[0] is float
)

У вас есть два условия, которые должны выполняться для выполнения утверждения. Первый -

len(list(map(type, (dictionary[key] for key in dictionary)))) is 1

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

Второе условие:

list(map(type, (dictionary[key] for key in dictionary)))[0] is float

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

Используя то, что вы уже написали, простой способ проверить это получить список типов, взять первый элемент и затем проверить, что все элементы равны к первому элементу.

l = list(map(type, (dictionary[key] for key in dictionary)))
for t in l: 
    self.assertTrue(t==l[0])

Но есть много способов сделать тест. Вы также можете преобразовать этот список в набор и проверить, что его длина равна единице (поскольку набор будет сохранять только уникальные значения)

self.assertTrue(len(set(l)) == 1)
# or self.assertEqual(len(set(l)), 1)
0 голосов
/ 01 мая 2020

Вы можете конвертировать типы предметов в набор и утверждать, что он равен набору float:

self.assertSetEqual(set(map(type, dictionary.values())), {float})
...