簡體   English   中英

一個班輪創建一個字典,其中包含另一個列表的值。 可能嗎?

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

我有以下代碼:

        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

是否可以使用 dict 理解或其他帶有 pos_table dict 的鍵和值的 dict rx_dctvals 進行單行初始化? 我很好奇。 這在一行中? 在這一個中,我與任務作斗爭:

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

這是整個代碼。 該腳本將 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()

如果你能看到更短的完成任務的方法,請告訴我。

當被問及評論時,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()}

我唯一的評論是,OP 使用了x[val] = key ,所以我這樣做了。 但是 OP,我希望你知道你用鑰匙打開一個寶箱。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM