Как создать вложенный словарь Python с ключами в виде строк? - PullRequest
0 голосов
/ 09 октября 2018

Краткое описание проблемы: я пытаюсь создать вложенный словарь Python с ключами, заданными предопределенными переменными и строками.И я заполняю словарь из регулярных выражений.Это в основном работает.Но я получаю сообщение об ошибке, потому что вложенный словарь - не основной - не любит, когда ключ имеет строку, он хочет целое число.Это смущает меня.Итак, я хотел бы спросить вас, ребята, как я могу получить вложенный словарь Python со строковыми ключами.

Ниже я расскажу вам о том, что я сделал.Что работает, а что нет.Начиная сверху:

# Regular expressions module
import re

# Read text data from a file
file = open("dt.cc", "r")
dtcc = file.read()

# Create a list of stations from regular expression matches
stations = sorted(set(re.findall(r"\n(\w+)\s", dtcc)))

Результат хороший и выглядит примерно так: station = ['AAAA', 'BBBB', 'CCCC', 'DDDD']

# Initialize a new dictionary
rows = {}

# Loop over each station in the station list, and start populating 
for station in stations:
    rows[station] = re.findall("%s\s(.+)" %station, dtcc)

Результат хороший и выглядит примерно так: row ['AAAA'] = ['AAAA 0.1132 0.32 P', ...]

Однако, когда я пытаюсь создать подпрограммусловарь со строковым ключом:

for station in stations:
    rows[station] = re.findall("%s\s(.+)" %station, dtcc)
    rows[station]["dt"] = re.findall("%s\s(\S+)" %station, dtcc)

Я получаю следующую ошибку.

"Ошибка типа: индексы списка должны быть целыми числами, а не str"

Не похоже, что я указываю второй ключ словаря как "dt".Если я вместо этого дам ему номер, он будет работать нормально.Но тогда имя моего словарного ключа - это число, которое не очень наглядно.

Есть мысли о том, как заставить это работать?

1 Ответ

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

Проблема заключается в том, что, делая

rows[station] = re.findall(...)

, вы создаете словарь с именами станций в качестве ключей и возвращаемым значением метода re.findall в качестве значений, которые оказываются списками.Поэтому, вызывая их снова с помощью

rows[station]["dt"] = re.findall(...)

на LHS row[station], вы получаете список, индексированный целыми числами, на что жалуется TypeError.Например, вы можете сделать rows[station][0], вы получите первое совпадение от регулярного выражения.Вы сказали, что хотите вложенный словарь.Вы можете сделать

rows[station] = dict()
rows[station]["dt"] = re.findall(...)

Чтобы сделать его немного лучше, структура данных, которую вы могли бы использовать вместо этого, - это defaultdict из collections модуля.

defaultdict - это словарь, который принимает тип по умолчанию в качестве типа для своих значений.Вы вводите конструктор типа в качестве аргумента.Например, dictlist = defaultdict(list) определяет словарь, имеющий списки значений!Тогда немедленное выполнение dictlist[key].append(item1) является законным, так как список автоматически создается при установке ключа.

В вашем случае вы можете сделать

from collections import defaultdict

rows = defaultdict(dict)

for station in stations:
    rows[station]["bulk"] = re.findall("%s\s(.+)" %station, dtcc)
    rows[station]["dt"] = re.findall("%s\s(\S+)" %station, dtcc)

, где вы должны назначить первый результат регулярного выражения дляновый ключ, "bulk" здесь, но вы можете называть его как хотите.Надеюсь, это поможет.

...