Как преобразовать строковое значение словаря в логические значения? - PullRequest
0 голосов
/ 02 октября 2018

Я создал словарь, содержащий ключи и значения.После прочтения текстового файла, такого как:

test1
    House: True
    Car: False
    Money: False
    Case: 1

test2
    House: True
    Car: False
    Money: False
    Case: 2

test3
    House: True
    Car: False
    Money: False
    Case: 3

словарь создается.Проблема в том, что значения читаются как строки.Мне нужно, чтобы они были как bools, чтобы потом я мог анализировать их в файл JSON и использовать там как bools.Созданный словарь называется answer.Я попробовал следующее, но это только дает мне True как логическое значение:

    to_json = {}
    block_cnt = 1
    header = re.compile('[a-zA-Z0-9]')
    inner = re.compile("[\t]")
    empty = re.compile("[\n]",)`

    with open(rDEMO_parameters.txt', 'r') as document:
    for line in document:
        #print line
        if empty.match(line[0]):
            continue

        elif header.match(line[0]):
            if answer:
                to_json[block_cnt] = answer
                #print answer
                block_cnt += 1
                answer = {}
        elif inner.match(line[0]):
            _key, value = line.split(":  ")
            tab, key = _key.split("\t")
            answer[key] = value.split()
           for key in answer.keys():
            if key == "House":
                answer[key] = map(bool, answer[key])
            if key == "Car":
                answer[key] = map(bool, answer[key])
            if key == "Money":
                answer[key] = map(bool, answer[key])
            if key == "Case":
                answer[key] = map(int, answer[key])


   f = open(r"parameters.json", "w")

   json.dump(to_json, f)
   f.close()

Затем после преобразования я получаю только что-то подобное, но все в одной строке:

 {1
   {
    House: True
    Car: True
    Money: True
    Case: [1]
             } }
 {2
   {
    House: True
    Car: True
    Money: True
    Case: [2] } }
 {3
    {
    House: True
    Car: True
    Money: True
    Case: [3] }}

Таким образом, все строки преобразуются в True логические значения, что не так.Другая проблема заключается в том, что значения читаются внутри списков.Есть ли способ избежать этого?Спасибо.

Ответы [ 4 ]

0 голосов
/ 02 октября 2018

Если я понимаю, что ваши bool - это строки, и вам нужно, чтобы они действительно были bools, если да, то понимание словаря будет работать

d = {k: True if d[k] == 'True' else False for k in d}
 {'House': True, 'Car': False, 'Money': False}
0 голосов
/ 02 октября 2018

map используется для применения функции к каждому значению в итерируемом.

Вместо этого можно использовать ast.literal_eval:

from ast import literal_eval

answer[key] = literal_eval(answer[key])

Кроме того,вам не нужно проверять каждый ключ в отдельной инструкции if.Также идиоматичнее итерировать по dict.items, если вы используете и ключ и значение в своей логике:

for key, value in answer.items():
    if key in ('House', 'Car', 'Money'):
        answer[key] = literal_eval(value)

Наконец, вместо этого рассмотрите возможность использования словарного понимания:

# for modifying over all values
answer = {k: literal_eval(v) for k, v in answer.items()}

# for modifying selected values
select = {'House', 'Car', 'Money'}
answer = {k: literal_eval(v) if k in select else v for k, v in answer.items()}
0 голосов
/ 02 октября 2018

Почему бы просто:

for key in answer.keys():
   answer[key] = answer[key] == "True"
0 голосов
/ 02 октября 2018

map(bool, answer[key]) отображает функцию на символы строки.Все непустые символы имеют значение true, поэтому вы должны ожидать, что получите только True.

Вам нужно проверить == "True"

Другими словами, результат bool("False") может вас удивить

...