print - python dictionary methods
¿Cómo se crea dict anidado en Python? (4)
Es importante recordar que al usar defaultdict y módulos dict anidados similares como nested_dict, la búsqueda de una clave inexistente puede crear inadvertidamente una nueva entrada de clave en el diccionario y causar muchos estragos. Aquí hay un ejemplo de Python3 con nested_dict.
import nested_dict as nd
nest = nd.nested_dict()
nest[''outer1''][''inner1''] = ''v11''
nest[''outer1''][''inner2''] = ''v12''
print(''original nested dict: /n'', nest)
try:
nest[''outer1''][''wrong_key1'']
except KeyError as e:
print(''exception missing key'', e)
print(''nested dict after lookup with missing key. no exception raised:/n'', nest)
# instead convert back to normal dict
nest_d = nest.to_dict(nest)
try:
print(''converted to normal dict. Trying to lookup Wrong_key2'')
nest_d[''outer1''][''wrong_key2'']
except KeyError as e:
print(''exception missing key'', e)
else:
print('' no exception raised:/n'')
# or use dict.keys to check if key in nested dict.
print(''checking with dict.keys'')
print(list(nest[''outer1''].keys()))
if ''wrong_key3'' in list(nest.keys()):
print(''found wrong_key3'')
else:
print('' did not find wrong_key3'')
La salida es:
original nested dict: {"outer1": {"inner2": "v12", "inner1": "v11"}}
nested dict after lookup with missing key. no exception raised:
{"outer1": {"wrong_key1": {}, "inner2": "v12", "inner1": "v11"}}
converted to normal dict.
Trying to lookup Wrong_key2
exception missing key ''wrong_key2''
checking with dict.keys
[''wrong_key1'', ''inner2'', ''inner1'']
did not find wrong_key3
Tengo 2 archivos csv. El primero es un archivo de datos y otro es un archivo de mapeo. El archivo de asignación tiene 4 columnas Device_Name GDN Device_Type Device_OS
Estas son también las columnas que están presentes en el archivo de datos y necesitan ser trabajadas.
El archivo de datos contiene datos con la columna Device_Name poblada y resto 3 columnas en blanco. El archivo de asignación contiene todas las columnas pobladas. Quiero que mi código de Python abra ambos archivos y para cada nombre de dispositivo en el archivo de datos correlacione su GDN, Device_Type y Device_OS desde el archivo de mapeo.
Sé cómo usar dict cuando solo están presentes 2 columnas (se necesita 1 para mapear) pero no sé cómo lograr esto cuando se deben mapear 3 columnas.
A continuación se muestra el código con el que traté de realizar la asignación de Device_Type
:
x = dict([])
with open("Pricing Mapping_2013-04-22.csv", "rb") as in_file1:
file_map = csv.reader(in_file1, delimiter='','')
for row in file_map:
typemap = [row[0],row[2]]
x.append(typemap)
with open("Pricing_Updated_Cleaned.csv", "rb") as in_file2, open("Data Scraper_GDN.csv", "wb") as out_file:
writer = csv.writer(out_file, delimiter='','')
for row in csv.reader(in_file2, delimiter='',''):
try:
row[27] = x[row[11]]
except KeyError:
row[27] = ""
writer.writerow(row)
Devuelve el Atribute Error
.
Después de investigar un poco, me di cuenta de que necesito crear un dictado anidado, pero no tengo idea de cómo hacerlo. Por favor, ayúdame a resolver esto o empujarme en la dirección correcta para resolver esto.
Para niveles arbitrarios de anidamiento:
In [2]: def nested_dict():
...: return collections.defaultdict(nested_dict)
...:
In [3]: a = nested_dict()
In [4]: a
Out[4]: defaultdict(<function __main__.nested_dict>, {})
In [5]: a[''a''][''b''][''c''] = 1
In [6]: a
Out[6]:
defaultdict(<function __main__.nested_dict>,
{''a'': defaultdict(<function __main__.nested_dict>,
{''b'': defaultdict(<function __main__.nested_dict>,
{''c'': 1})})})
Un dict anidado es un diccionario dentro de un diccionario. Una cosa muy simple.
>>> d = {}
>>> d[''dict1''] = {}
>>> d[''dict1''][''innerkey''] = ''value''
>>> d
{''dict1'': {''innerkey'': ''value''}}
También puede usar un valor defaultdict
del paquete de collections
para facilitar la creación de diccionarios anidados.
>>> import collections
>>> d = collections.defaultdict(dict)
>>> d[''dict1''][''innerkey''] = ''value''
>>> d # currently a defaultdict type
defaultdict(<type ''dict''>, {''dict1'': {''innerkey'': ''value''}})
>>> dict(d) # but is exactly like a normal dictionary.
{''dict1'': {''innerkey'': ''value''}}
Puedes poblar eso como quieras.
Yo recomendaría en tu código algo así como lo siguiente:
d = {} # can use defaultdict(dict) instead
for row in file_map:
# derive row key from something
# when using defaultdict, we can skip the next step creating a dictionary on row_key
d[row_key] = {}
for idx, col in enumerate(row):
d[row_key][idx] = col
De acuerdo a tu comment :
puede estar por encima del código confundiendo la pregunta. Mi problema en pocas palabras: tengo 2 archivos a.csv b.csv, a.csv tiene 4 columnas ijkl, b.csv también tiene estas columnas. es un tipo de columnas clave para estos csvs ''. La columna jkl está vacía en a.csv pero está poblada en b.csv. Quiero mapear valores de jk l columnas usando ''i` como columna clave de b.csv a un archivo .csv
Mi sugerencia sería algo como esto (sin usar defaultdict):
a_file = "path/to/a.csv"
b_file = "path/to/b.csv"
# read from file a.csv
with open(a_file) as f:
# skip headers
f.next()
# get first colum as keys
keys = (line.split('','')[0] for line in f)
# create empty dictionary:
d = {}
# read from file b.csv
with open(b_file) as f:
# gather headers except first key header
headers = f.next().split('','')[1:]
# iterate lines
for line in f:
# gather the colums
cols = line.strip().split('','')
# check to make sure this key should be mapped.
if cols[0] not in keys:
continue
# add key to dict
d[cols[0]] = dict(
# inner keys are the header names, values are columns
(headers[idx], v) for idx, v in enumerate(cols[1:]))
Sin embargo, tenga en cuenta que para analizar archivos csv hay un módulo csv .
ACTUALIZACIÓN : para una longitud arbitraria de un diccionario anidado, vaya a esta respuesta .
Use la función defaultdict de las colecciones.
Alto rendimiento: "si la clave no está en dict" es muy costosa cuando el conjunto de datos es grande.
Bajo mantenimiento: haga que el código sea más legible y se pueda extender fácilmente.
from collections import defaultdict
target_dict = defaultdict(dict)
target_dict[key1][key2] = val