Как мне реализовать многоключевой хэш в Perl как вложенный словарь в Python? - PullRequest
0 голосов
/ 18 февраля 2019

У меня есть некоторый базовый код для работы с хэшем Perl, где я могу обращаться к таким элементам, как: $ data {"WV2"} {789} {PP1} (или использовать этот фактический текст в назначении) ... но яхотел бы сделать что-то подобное, используя словари Python.

Несколько простых программ на Perl и Python, которые иллюстрируют то, что я пытался повторить, следуют: -

Итак, Perlкод: -

# hash.pl

use strict;
use warnings;

use Data::Dumper;

my %data = ();

my @reg_list = ( "MC1", "CA2", "WV2" );
my @site_list = ( 123, 456, 391, 287 );

$data{MC1}{4564}{PP}{1} = "-15,-15C";
$data{MC1}{4564}{PP}{2} = "5,5C";
$data{MC1}{4564}{PP}{3} = "-19,-19C";
$data{MC1}{4564}{PP}{4} = "-12,-12C";

printf("---- One:\n");
print Dumper(%data);                 # Ok, shows the full strucure

printf("---- Two:\n");
print Dumper($data{"MC2"});          # Shows as undef (sensible)

printf("---- Three:\n");
print Dumper($data{"MC1"});          # Ok, showing the key:values for each "site" key

printf("---- Four:\n");
print Dumper($data{"MC1"}{"4564"});  # Ok, shows the actual equality value above


# ---- This works Ok

my %xdata = ();
$xdata{"MC1"}{123}{"PP"} = "-15,-15C";
$xdata{"MC1"}{456}{"PP"} = "5,5C";
$xdata{"MC1"}{391}{"PP"} = "-19,-19C";
$xdata{"MC1"}{287}{"PP"} = "-12,-12C";

printf("---- One:\n");
print Dumper(%xdata);                # Ok, shows the full strucure


#pprint.pprint(data["MC2"]) 
#pprint.pprint(data["MC1"}{391]) 


# [eof]

... и код Python: -

# dict.py

import pprint
import collections

reg_list  = [ "MC1", "CA2", "WV2" ]
site_list = [ 123, 456, 391, 287 ]

#data = {}
data = collections.defaultdict(dict) # {}
data["MC1"][123] = "-15,-15C"
data["MC1"][456] = "5,5C"
data["MC1"][391] = "-19,-19C"
data["MC1"][287] = "-12,-12C"

print("---- One:")
pprint.pprint(data)              # Ok, shows the full strucure

print("---- Two:")
pprint.pprint(data["MC2"])       # Shows: {} [...Ok, undefined...]

print("---- Three:")
pprint.pprint(data["MC1"])       # Ok, showing the key:values for each "site" key

print("---- Four:")
pprint.pprint(data["MC1"][391])  # Ok, shows the actual equality value above

# ---- Cannot get the following to work

xdata = collections.defaultdict(dict) # {}
xdata["MC1"][123]["PP"] = "-15,-15C"  # ERROR: Key error 123
xdata["MC1"][456]["PP"] = "5,5C"
xdata["MC1"][391]["PP"] = "-19,-19C"
xdata["MC1"][287]["PP"] = "-12,-12C"

#pprint.pprint(data["MC2"]) 
#pprint.pprint(data["MC1"][391]) 

# [eof]

Выводы для каждой из программ следующие: -

# Perl Output:

---- One:
$VAR1 = 'MC1';
$VAR2 = {
          '4564' => {
                      'PP' => {
                                '4' => '-12,-12C',
                                '1' => '-15,-15C',
                                '3' => '-19,-19C',
                                '2' => '5,5C'
                              }
                    }
        };
---- Two:
$VAR1 = undef;
---- Three:
$VAR1 = {
          '4564' => {
                      'PP' => {
                                '4' => '-12,-12C',
                                '1' => '-15,-15C',
                                '3' => '-19,-19C',
                                '2' => '5,5C'
                              }
                    }
        };
---- Four:
$VAR1 = {
          'PP' => {
                    '4' => '-12,-12C',
                    '1' => '-15,-15C',
                    '3' => '-19,-19C',
                    '2' => '5,5C'
                  }
        };
---- One:
$VAR1 = 'MC1';
$VAR2 = {
          '391' => {
                     'PP' => '-19,-19C'
                   },
          '456' => {
                     'PP' => '5,5C'
                   },
          '123' => {
                     'PP' => '-15,-15C'
                   },
          '287' => {
                     'PP' => '-12,-12C'
                   }
        };

...и из Python: -

# Python Output:-

---- One:
defaultdict(<class 'dict'>,
            {'MC1': {123: '-15,-15C',
                     287: '-12,-12C',
                     391: '-19,-19C',
                     456: '5,5C'}})
---- Two:
{}
---- Three:
{123: '-15,-15C', 287: '-12,-12C', 391: '-19,-19C', 456: '5,5C'}
---- Four:
'-19,-19C'
Traceback (most recent call last):
  File "C:\Projects\00-Development\LXQuery\CDB-Review\dict.py", line 30, in <module>
    xdata["MC1"][123]["PP"] = "-15,-15C"  # ERROR: Key error 123
KeyError: 123

Я пытался найти информацию о словарях вложений ... но все, на что я смотрел, не дает четкого объяснения того, как концепция должна работать(по-моему, в любом случае) .... особенно, когда используются «более глубокие» уровни словарей.

Я пишу код на Perl ~ 25 лет, но только начинаю с Python.

Запуск ActiveState Perl v5.16.3, сборка 1603 и Anaconda Python 3.6.5 под Windows 10 x64.

Большое спасибо за любые мысли или предложения.

Ответы [ 2 ]

0 голосов
/ 20 февраля 2019

Простой способ обойти проблему выглядит примерно так: -

xdata = collections.defaultdict(dict) # {}
xdata["MC1"][123] = {}                # Define the dict before using it
xdata["MC1"][123]["PP"] = "-15,-15C"  # Works Ok

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

Несмотря на присущие Считайте! из-за неправильного набора и (возможного) повреждения содержимого dict, Что такоелучший способ реализовать вложенные словари? кажется хорошим способом справиться с проблемой ... особенно если значения (в любом случае, в моем текущем приложении) "никогда не видят свет" (они генерируются машиной)и проверено перед входом в мое приложение) ... Итак, некоторый код, который, вероятно, сработает, может быть: -

class Vividict(dict):
    def __missing__(self, key):
        value = self[key] = type(self)() # retain local pointer to value
        return value                     # faster to return than 
                                         # ...'dict lookup'

ydata = Vividict()

ydata["MC1"][123]["PP"] = "-15,-15C"
ydata["MC1"][456]["PP"] = "5,5C"
ydata["MC1"][391]["PP"] = "-19,-19C"
ydata["MC1"][287]["PP"] = "-12,-12C"

pprint.pprint(ydata)              # Ok, shows the full strucure

Спасибо за кучу предложений и указателей.

0 голосов
/ 18 февраля 2019

Python не выполняет автовивификацию многоуровневых словарей, как это делает Perl со своими хешами.На втором и более глубоких уровнях вы должны присвоить пустые dict более высокому уровню dict с, прежде чем добавлять к ним дополнительные ключи:

xdata = collections.defaultdict(dict)
xdata["MC1"] = collections.defaultdict(dict)
xdata["MC1"][123]["PP"] = "-15,-15C"  # ERROR: Key error 123
xdata["MC1"][456]["PP"] = "5,5C"
xdata["MC1"][391]["PP"] = "-19,-19C"
xdata["MC1"][287]["PP"] = "-12,-12C"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...