Heim >Backend-Entwicklung >Golang >Konvertieren Sie durch Punkte getrennte Werte mit Python in eine Go-Struktur
php-Editor Youzi stellt in diesem Artikel vor, wie man mit Python durch Punkte getrennte Werte (wie „key1.subkey1.subkey2“) in eine Struktur in der Go-Sprache umwandelt. Dieser Transformationsprozess ist nützlich zum Extrahieren und Verarbeiten von Daten aus Konfigurationsdateien oder API-Antworten. Wir werden die rekursiven Funktionen und Go-Sprachstrukturen von Python verwenden, um diese Konvertierung zu implementieren, und detaillierte Codebeispiele und Erklärungen geben. Nach dem Studium dieses Artikels werden die Leser in der Lage sein, punktgetrennte Werte problemlos zu verarbeiten und umzuwandeln, wodurch die Effizienz und Flexibilität der Datenverarbeitung verbessert wird.
Dies ist eine spezifische Anforderung für eine Anwendung, die die Konfiguration ändern kann (insbesondere den WSO2-Identitätsserver, da ich Go verwende, um den Kubernetes-Operator dafür zu schreiben). Aber das ist hier wirklich nicht relevant. Ich möchte eine Lösung erstellen, die eine einfache Verwaltung einer großen Anzahl von Konfigurationskarten ermöglicht, um Go-Strukturen zu generieren. Diese Konfigurationen werden in .csv
abgebildetLink zu .csv – my_configs.csv
Ich möchte, Schreiben Sie ein Python-Skript, das automatisch Go-Strukturen generiert, damit alle Änderungen an der Anwendungskonfiguration aktualisiert werden können, indem Sie einfach das Python-Skript ausführen, um die entsprechende Go-Struktur zu erstellen. Ich beziehe mich auf die Konfiguration der Anwendung selbst. Beispielsweise können ToML-Schlüsselnamen in CSV geändert/neue Werte hinzugefügt werden.
Bisher habe ich erfolgreich ein Python-Skript erstellt, das mein Ziel fast erreicht. Das Drehbuch lautet:
import pandas as pd def convert_to_dict(data): result = {} for row in data: current_dict = result for item in row[:-1]: if item is not none: if item not in current_dict: current_dict[item] = {} current_dict = current_dict[item] return result def extract_json_key(yaml_key): if isinstance(yaml_key, str) and '.' in yaml_key: return yaml_key.split('.')[-1] else: return yaml_key def add_fields_to_struct(struct_string,go_var,go_type,json_key,toml_key): struct_string += str(go_var) + " " + str(go_type) + ' `json:"' + str(json_key) + ',omitempty" toml:"' +str(toml_key) + '"` ' + "\n" return struct_string def generate_go_struct(struct_name, struct_data): struct_name="configurations" if struct_name == "" else struct_name struct_string = "type " + struct_name + " struct {\n" yaml_key=df['yaml_key'].str.split('.').str[-1] # base case: generate fields for the current struct level for key, value in struct_data.items(): selected_rows = df[yaml_key == key] if len(selected_rows) > 1: go_var = selected_rows['go_var'].values[1] toml_key = selected_rows['toml_key'].values[1] go_type=selected_rows['go_type'].values[1] json_key=selected_rows['json_key'].values[1] else: go_var = selected_rows['go_var'].values[0] toml_key = selected_rows['toml_key'].values[0] go_type=selected_rows['go_type'].values[0] json_key=selected_rows['json_key'].values[0] # add fields to the body of the struct struct_string=add_fields_to_struct(struct_string,go_var,go_type,json_key,toml_key) struct_string += "}\n\n" # recursive case: generate struct definitions for nested structs for key, value in struct_data.items(): selected_rows = df[yaml_key == key] if len(selected_rows) > 1: go_var = selected_rows['go_var'].values[1] else: go_var = selected_rows['go_var'].values[0] if isinstance(value, dict) and any(isinstance(v, dict) for v in value.values()): nested_struct_name = go_var nested_struct_data = value struct_string += generate_go_struct(nested_struct_name, nested_struct_data) return struct_string # read excel csv_file = "~/downloads/my_configs.csv" df = pd.read_csv(csv_file) # remove rows where all columns are nan df = df.dropna(how='all') # create the 'json_key' column using the custom function df['json_key'] = df['yaml_key'].apply(extract_json_key) data=df['yaml_key'].values.tolist() # read the 'yaml_key' column data = pd.dataframe({'column':data}) # convert to dataframe data=data['column'].str.split('.', expand=true) # split by '.' nested_list = data.values.tolist() # convert to nested list data=nested_list result_json = convert_to_dict(data) # convert to dict (json) # the generated co code go_struct = generate_go_struct("", result_json) # write to file file_path = "output.go" with open(file_path, "w") as file: file.write(go_struct)
Das Problem ist (siehe unten Teil der CSV),
authentication.authenticator.basic authentication.authenticator.basic.parameters authentication.authenticator.basic.parameters.showAuthFailureReason authentication.authenticator.basic.parameters.showAuthFailureReasonOnLoginPage authentication.authenticator.totp authentication.authenticator.totp.parameters authentication.authenticator.totp.parameters.showAuthFailureReason authentication.authenticator.totp.parameters.showAuthFailureReasonOnLoginPage authentication.authenticator.totp.parameters.encodingMethod authentication.authenticator.totp.parameters.timeStepSize
Hier, da es in der Spalte basic
和 totp
字段 parameters
重复,因此脚本会混淆自身并生成两个 totpparameters
结构。预期结果是具有 basicparameters
和 totpparameters
结构。 csv 的 yaml_key
viele ähnliche wiederholte Wörter gibt.
Ich weiß, dass das damit zu tun hat, dass der Index fest auf 1 in codiert ist go_var = selected_rows['go_var'].values[1]
, aber es ist schwer, das zu beheben.
Kann mir jemand eine Antwort geben? Ich denke,
Danke!
Ich habe auch versucht, chatgpt zu verwenden, aber da dies mit Verschachtelung und Rekursion zu tun hat, ist die von chatgpt bereitgestellte Antwort nicht sehr effizient.
Aktualisiert
Ich habe Duplikate in Spalten gefunden, die properties
、pooloptions
、endpoint
和 parameters
字段的行存在问题。这是因为它们在 yaml_key
enthalten.
Ich konnte dieses Problem lösen. Allerdings musste ich einen völlig neuen Ansatz für das Problem wählen, der darin bestand, eine Baumdatenstruktur zu verwenden und dann darüber zu iterieren. Das ist die Hauptlogik dahinter – https://www.geeksforgeeks.org/level-sequential tree traversal/
Dies ist der funktionierende Python-Code.
import pandas as pd from collections import deque structs=[] class TreeNode: def __init__(self, name): self.name = name self.children = [] self.path="" def add_child(self, child): self.children.append(child) def create_tree(data): root = TreeNode('') for item in data: node = root for name in item.split('.'): existing_child = next((child for child in node.children if child.name == name), None) if existing_child: node = existing_child else: new_child = TreeNode(name) node.add_child(new_child) node = new_child return root def generate_go_struct(struct_data): struct_name = struct_data['struct_name'] fields = struct_data['fields'] go_struct = f"type {struct_name} struct {{\n" for field in fields: field_name = field['name'] field_type = field['type'] field_default_val = str(field['default_val']) json_key=field['json_key'] toml_key=field['toml_key'] tail_part=f"\t{field_name} {field_type} `json:\"{json_key},omitempty\" toml:\"{toml_key}\"`\n\n" if pd.isna(field['default_val']): go_struct += tail_part else: field_default_val = "\t// +kubebuilder:default:=" + field_default_val go_struct += field_default_val + "\n" + tail_part go_struct += "}\n\n" return go_struct def write_go_file(go_structs, file_path): with open(file_path, 'w') as file: for go_struct in go_structs: file.write(go_struct) def create_new_struct(struct_name): struct_name = "Configurations" if struct_name == "" else struct_name struct_dict = { "struct_name": struct_name, "fields": [] } return struct_dict def add_field(struct_dict, field_name, field_type,default_val,json_key, toml_key): field_dict = { "name": field_name, "type": field_type, "default_val": default_val, "json_key":json_key, "toml_key":toml_key } struct_dict["fields"].append(field_dict) return struct_dict def traverse_tree(root): queue = deque([root]) while queue: node = queue.popleft() filtered_df = df[df['yaml_key'] == node.path] go_var = filtered_df['go_var'].values[0] if not filtered_df.empty else None go_type = filtered_df['go_type'].values[0] if not filtered_df.empty else None if node.path=="": go_type="Configurations" # The structs themselves current_struct = create_new_struct(go_type) for child in node.children: if (node.name!=""): child.path=node.path+"."+child.name else: child.path=child.name filtered_df = df[df['yaml_key'] == child.path] go_var = filtered_df['go_var'].values[0] if not filtered_df.empty else None go_type = filtered_df['go_type'].values[0] if not filtered_df.empty else None default_val = filtered_df['default_val'].values[0] if not filtered_df.empty else None # Struct fields json_key = filtered_df['yaml_key'].values[0].split('.')[-1] if not filtered_df.empty else None toml_key = filtered_df['toml_key'].values[0].split('.')[-1] if not filtered_df.empty else None current_struct = add_field(current_struct, go_var, go_type,default_val,json_key, toml_key) if (child.children): # Add each child to the queue for processing queue.append(child) go_struct = generate_go_struct(current_struct) # print(go_struct,"\n") structs.append(go_struct) write_go_file(structs, "output.go") csv_file = "~/Downloads/my_configs.csv" df = pd.read_csv(csv_file) sample_data=df['yaml_key'].values.tolist() # Create the tree tree = create_tree(sample_data) # Traverse the tree traverse_tree(tree)
Vielen Dank für Ihre Hilfe!
Das obige ist der detaillierte Inhalt vonKonvertieren Sie durch Punkte getrennte Werte mit Python in eine Go-Struktur. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!