Nano Hash - криптовалюты, майнинг, программирование

Эквивалентная реализация Perl Hash of Hashes для dict of dicts в Tcl

У меня есть очень большой файл, содержащий данные, как показано ниже:

*1 RES L1 N1 0.32
*22 RES L2 N2 0.64

*100 CAP A1 B1 0.3
*200 CAP A2 B1 0.11

*11 IND K1 K2 0.002
*44 IND X1 Y1 0.00134

... and so on

Для таких файлов (предположим, что приведенные выше данные находятся в файле с именем «example.txt»), я могу легко создать хэш хэшей в Perl и передать эти вложенные хэши в другие части моей программы Perl:

#!/usr/bin/perl
use strict;
use warnings;

open(FILE,"<", "example.txt") or die "Cannot open file:$!";
if (-f "example.txt") {
 while(<FILE>) {
  chomp;
  if(/^\s*(\S+)\s+(RES|CAP|IND)\s+(\S+)\s+(\S+)\s+(\S+)\s*$/) {
   $hoh{$1}{$2}{$3}{$4} = $5;
  }
 }
 close FILE;
}

Каков аналогичный способ создания Tcl Hash of Hashes (или, скорее, Dictionary of Dictionaries)?

Я попробовал небольшой фрагмент кода, устанавливающий словарь, как показано ниже (не печатая здесь полный код, чтобы сосредоточиться на проблеме):

  ...
  set dod [dict create]

  if [regexp {^\s*(\S+)\s+(RES|CAP|IND)\s+(\S+)\s+(\S+)\s+(\S+)\s*$} $line all id type x y elemValue] {
   dict set dod $id $type $x $y $elemValue
  }

Но это, похоже, не работает. Я проверил это, как показано ниже:

foreach id [dict keys $dod] {
 if [dict exists $dod "RES"] {
  puts "RES KEY EXISTS"
 } else {
  puts "RES KEY NOT FOUND"
 }
}

Спасибо.

31.12.2017

Ответы:


1

Ваша непосредственная проблема - случайная косая черта в начале регулярного выражения.

Чтобы ответить на вопрос: многоключевой словарь является "хэшем хэшей". Каждый ключ добавляет новый уровень словарей.

dict set foo aa bb cc 1

устанавливает элемент {cc 1} в словаре, который является значением элемента {bb ...} в словаре, который является значением элемента {aa ...} в foo.

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

dict set foo [list aa bb cc] 1

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

if {[lindex $line 1] in {RES CAP IND}} {
    dict set dod {*}$line
}

Но если вы хотите проверить существование, например. «RES», вам нужно установить его как ключ верхнего уровня, которого нет в вашем примере (элементы в первом столбце становятся ключами верхнего уровня). При инициализации, как указано выше, значение dod равно

*1 {RES {L1 {N1 0.32}}} *22 {RES {L2 {N2 0.64}}} *100 {CAP {A1 {B1 0.3}}} *200 {CAP {A2 {B1 0.11}}} *11 {IND {K1 {K2 0.002}}} *44 {IND {X1 {Y1 0.00134}}}

так что вы получаете словарь, но dict exists $dod RES по-прежнему обязательно ложно. Используя

if {[lindex $line 1] in {RES CAP IND}} {
    dict set dod {*}[lrange $line 1 end]
}

(т.е. все элементы в строке после первого как ключи, кроме последнего, который становится значением) вы получаете словарь

RES {L1 {N1 0.32} L2 {N2 0.64}} CAP {A1 {B1 0.3} A2 {B1 0.11}} IND {K1 {K2 0.002} X1 {Y1 0.00134}}

в котором можно проверить наличие "RES".

Возвращаясь к диктату диктов

*1 {RES {L1 {N1 0.32}}} *22 {RES {L2 {N2 0.64}}} *100 {CAP {A1 {B1 0.3}}} *200 {CAP {A2 {B1 0.11}}} *11 {IND {K1 {K2 0.002}}} *44 {IND {X1 {Y1 0.00134}}}

вы можете проверить «RES», изучив каждый из подсловарей, пока не найдете тот, в котором есть этот ключ:

set found 0
dict for {key subdict} $dod {
    if {[dict exists $subdict RES]} {
        set found 1
        break
    }
}

Документация: dict

31.12.2017
  • Питер, извините, в моем копировании/вставке исходного вопроса была ошибка. Для части Tcl регулярное выражение должно было быть: `if [regexp {^\s*(\S+)\s+(RES|CAP|IND)\s+(\S+)\s+(\S+)\s+(\S+ )\s*$} $строка ...` 31.12.2017
  • Если вы делаете что-то действительно сложное с запросом данных, выгрузить их в базу данных SQLite в памяти несложно. 31.12.2017
  • Привет, Донал. Есть ли какая-нибудь документация о том, как использовать Tcl с SQLite в памяти? Я хочу попробовать это, чтобы увидеть, смогу ли я использовать это решение в будущем. Спасибо. 02.01.2018
  • @user3512999: Я не знаю, какая документация самая лучшая, но вы смотрели здесь: tcl.tk/man/tcl/SqliteCmd/sqlite3.htm 02.01.2018

  • 2

    Не совсем то же самое, но чем-то похоже:

    set data "*1 RES L1 N1 0.32
    *22 RES L2 N2 0.64
    
    *100 CAP A1 B1 0.3
    *200 CAP A2 B1 0.11
    
    *11 IND K1 K2 0.002
    *44 IND X1 Y1 0.00134
    "
    
    set pattern {\s*(\S+)\s+(RES|CAP|IND)\s+(\S+)\s+(\S+)\s+(\S+)?\s*$}
    set result [regexp -all -line -inline -- $pattern $data]
    
    if {[llength $result] == 0} {
        puts "Not found"
        exit 1
    }
    
    array set my_data {}
    foreach {all ind_0 ind_1 ind_2 ind_3 ind_4} $result {
        set my_data($ind_0)($ind_1)($ind_2)($ind_3) $ind_4
    }
    puts [parray my_data]
    

    Пример вывода:

    my_data(*1)(RES)(L1)(N1)   = 0.32
    my_data(*100)(CAP)(A1)(B1) = 0.3
    my_data(*11)(IND)(K1)(K2)  = 0.002
    my_data(*200)(CAP)(A2)(B1) = 0.11
    my_data(*22)(RES)(L2)(N2)  = 0.64
    my_data(*44)(IND)(X1)(Y1)  = 0.00134
    
    31.12.2017
  • Обратите внимание, что это не хэш хэшей, а одноуровневый ассоциативный массив со сложным ключом. 31.12.2017
  • Обратите внимание, что Tcl не поддерживает многомерные ключи. ключ для первого элемента выше - *1)(RES)(L1)(N1. Он по-прежнему работает, но используемый формат подразумевает некоторую функциональность, которой не существует. Я бы использовал другой разделитель, чем )(. Запятые, тире, точки — это хорошо. Если ключи необходимо отсортировать, следует тщательно выбирать формат ключа. 31.12.2017
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..