web-dev-qa-db-de.com

Wie erstellt man verschachtelte Diktate in Python?

Ich habe 2 CSV-Dateien. Die erste ist eine Datendatei und die andere ist eine Zuordnungsdatei. Die Zuordnungsdatei hat 4 Spalten: Device_Name, GDN, Device_Type und Device_OS. Dieselben Spalten sind in der Datendatei vorhanden.

Die Datendatei enthält Daten, wobei die Spalte Device_Name aufgefüllt ist und die anderen drei Spalten leer sind. Alle vier Spalten werden in der Zuordnungsdatei aufgefüllt. Ich möchte, dass mein Python-Code beide Dateien öffnet und für jeden Device_Name in der Datendatei seinen GDN-, Device_Type- und Device_OS-Wert aus der Mapping-Datei zuordnen.

Ich weiß, wie man dict verwendet, wenn nur 2 Spalten vorhanden sind (1 muss zugeordnet werden), aber ich weiß nicht, wie dies zu erreichen ist, wenn 3 Spalten zugeordnet werden müssen.

Nachfolgend ist der Code, mit dem ich versucht habe, Device_Type zu mappen:

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)

Es gibt den Atribute Error zurück.

Nach einigen Nachforschungen wurde mir klar, dass ich ein verschachteltes Diktat erstellen muss, aber ich habe keine Ahnung, wie das geht. Bitte helfen Sie mir bei der Lösung dieses Problems oder stoßen Sie mich in die richtige Richtung, um das Problem zu lösen. 

110
atams

Ein verschachteltes Dikt ist ein Wörterbuch innerhalb eines Wörterbuchs. Eine sehr einfache Sache.

>>> d = {}
>>> d['dict1'] = {}
>>> d['dict1']['innerkey'] = 'value'
>>> d
{'dict1': {'innerkey': 'value'}}

Sie können auch ein defaultdict aus dem collections -Paket verwenden, um das Erstellen von verschachtelten Wörterbüchern zu erleichtern.

>>> 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'}}

Sie können das befüllen, wie Sie möchten.

Ich würde in Ihrem Code etwas wie folgendes empfehlen:

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

Entsprechend Ihrem Kommentar :

möglicherweise liegt der Code über der Frage. Mein Problem in Kürze: Ich habe 2 Dateien a.csv b.csv, a.csv hat 4 Spalten i j k l, b.csv hat auch diese Spalten. Ich bin eine Art Schlüsselspalten für diese CSVs. j k l Spalte ist in a.csv leer, aber in b.csv ausgefüllt. Ich möchte Werte von j k .__ zuordnen. l Spalten mit "i" als Schlüsselspalte von b.csv zu einer.csv-Datei

Mein Vorschlag wäre etwas like this (ohne defaultdict zu verwenden):

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:]))

Bitte beachten Sie jedoch, dass zum Analysieren von CSV-Dateien ein csv-Modul vorhanden ist.

228
Inbar Rose

UPDATE: Für eine beliebige Länge eines verschachtelten Wörterbuchs gehen Sie zu diese Antwort .

Verwenden Sie die defaultdict-Funktion aus den Sammlungen. 

Hohe Leistung: "Wenn der Schlüssel nicht im Diktat ist" ist sehr teuer, wenn der Datensatz groß ist.

Geringer Wartungsaufwand: Der Code wird lesbarer und kann leicht erweitert werden.

from collections import defaultdict

target_dict = defaultdict(dict)
target_dict[key1][key2] = val
54
Junchen

Für beliebige Schachtelungsebenen:

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})})})
17
andrew

Wenn Sie defaultdict und ähnliche verschachtelte Diktormodule wie nested_dict verwenden, ist es wichtig zu wissen, dass das Nachschlagen eines nicht vorhandenen Schlüssels versehentlich einen neuen Schlüsseleintrag im Diktat erstellt und eine Menge Chaos verursacht. Hier ist ein Python3-Beispiel mit 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')

Ausgabe ist:

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
0
Skysail