简体   繁体   English

一个班轮创建一个字典,其中包含另一个列表的值。 可能吗?

[英]one liner to create a dictionnary with values of list an an other one. Is it possible?

I have the following code:我有以下代码:

        rx_dctvals = {}
        for key, val in pos_table.items():
            rx_dctvals[re.compile("|".join(sorted([to_regex(v) for v in val], key=len, reverse=True)))] = key

Is it possible to make a one liner initialization for dict rx_dctvals using dict comprehension or other with the keys, values of pos_table dict?是否可以使用 dict 理解或其他带有 pos_table dict 的键和值的 dict rx_dctvals 进行单行初始化? I'm curious.我很好奇。 And this in one line?这在一行中? In this one, i struggle with assignment:在这一个中,我与任务作斗争:

for rx, repl in rx_dctvals.items():
     line = rx.sub(repl.replace('\\', '\\\\'), line)

Here is the entire code.这是整个代码。 This script changes POS (parts of speech of words from Penn Treebank to standard POS. It prints also NER (name entity recognition) of each word. It load a table of equivalence between pos from file and set a regex to change them.该脚本将 POS(词的词性从 Penn Treebank 更改为标准 POS。它还打印每个单词的 NER(名称实体识别)。它从文件中加载 pos 之间的等价表并设置一个正则表达式来更改它们。

# -*- coding: utf-8 -*-
#!usr/bin/env python3

import nltk
from nltk.tokenize import sent_tokenize, word_tokenize
from nltk import ne_chunk, pos_tag
from nltk.chunk import tree2conlltags
import re
import sys

# fonction qui charge le premier dictionnaire de données (valeurs particulières, valeurs universelles, étiquètes POS et NER)
# c'est ce qui va servir de base pour la construction de nos regex.
def load_pos_table():

    try:
         
        with open('POSTags_PTB_Universal_Linux.txt', 'r', encoding='utf-8') as universal:

            dict_pos = {}
            for sent in universal.readlines():
                for line in sent.splitlines():
                    cut = line.strip().split()
                    dict_pos[cut[1]] = dict_pos.get(cut[1], list()) + [cut[0]]

        return dict_pos

    except Exception as erreur:
        print(f'load_pos_table : {erreur}')

# fonction qui utilise un solide module regex pour supprimer les formes non standards (POS tag et NER) et les remplacer par les formes universelles
# cette fonction a l'avantage d’être générique et peut s’appliquer partout pour remplacer tout ce que l'on souhaite. Elle se base sur un dictionnaire.
def convert_format(line, pos_table):

    try:
        # comme il peut y avoir plusieurs formes non standards pour une forme universelle, on crée un regex d’agrégation en triant les valeurs par ordre décroissant de taille
        # pour éviter les conflits de remplacements. C'est la clé du dictionnaire. Sa valeur est l’étiquette universelle correspondante.
        rx_dctvals = {re.compile("|".join(sorted([to_regex(v) for v in val], key=len, reverse=True))):key for key, val in pos_table.items()}

        # on remplace séquentiellement nos valeurs non standards par leur équivalent universel avec notre liste de regex constituées précédemment.
        for rx, repl in rx_dctvals.items():
            line = rx.sub(repl.replace('\\', '\\\\'), line)
        
        return line

    except Exception as erreur:
        print(f'convert_tag: {erreur}')

# fonction pour bien définir les délimitations entre les mots dans les regex et pour échapper les caractères spéciaux.
def to_regex(x):

    r = []
    if x[0].isalnum() or x[0] == '_':
        r.append(r'(?<![^\W_])')
    else:
        if any(l.isalnum() or l=='_' for l in x):
            r.append(r'\B')
    r.append(re.escape(x))
    if x[-1].isalnum() or x[-1] == '_':
        r.append(r'\b')
    else:
        if any(l.isalnum() or l=='_' for l in x):
            r.append(r'\B')
    return "".join(r)

# fonction qui extrait les entités nommées en se basant sur le package ne_chunk et qui pos tag tous les mots également
# elle renvoie le résultat sous forme d'une liste de tuples.
def extract_entities(doc):

    # on tokenise et on extrait les entités nommées avec ne_chunk.
    return [tree2conlltags(ne_chunk(pos_tag(word_tokenize(sent)))) for sent in sent_tokenize(doc)]

def main():

    try:

        with open('wsj_0010_sample.txt', 'r', encoding='utf-8') as file, open('wsj_0010_sample.txt.ne.nltk', 'w', encoding='utf-8') as result_file:

            pos_table = load_pos_table()
            content = file.read()

            # on écrit un mot par ligne dans le fichier de résultats avec son POS et son NER (séparés par une tabulation (format universel ou standard)
            # grace à une list comprehension
            [[result_file.write(convert_format(f'{name}\t{tag}\t{ner}\n', pos_table)) for name, tag, ner in line] for line in extract_entities(content)]

    except Exception as error:
        print(f'main error : {error}')

if __name__ == '__main__':
    main()

If you can see a shorter way to do a task, tell me.如果你能看到更短的完成任务的方法,请告诉我。

Asked a comment, OP said it worked, turning it into an answer.当被问及评论时,OP 说它有效,并将其变成了答案。

rx_dctvals = {re.compile("|".join(sorted([to_regex(v) for v in val], key=len, reverse=True))):key for key, val in pos_table.items()}

My only comment to make Is, the OP used x[val] = key , so I am doing so.我唯一的评论是,OP 使用了x[val] = key ,所以我这样做了。 But OP, I hope you know you use a key to open a chest of goodies.但是 OP,我希望你知道你用钥匙打开一个宝箱。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM