как вы создаете вложенный dict в python?

<p>у меня есть 2 csv-файла. первый файл данных, а другой файл сопоставления. файл сопоставления имеет 4 столбца: <code>device\_name</code>, <code>gdn</code>, <code>device\_type</code> и <code>device\_os</code>. те же столбцы присутствуют в файле данных.</p><p>файл данных содержит данные с заполненным столбцом <code>device\_name</code>, а остальные три столбца пустыми. все четыре столбца заполняются в файле сопоставления. я хочу, чтобы мой код python открывал оба файла и для каждого <code>device\_name</code> в файле данных сопоставлял его значения <code>gdn</code>, <code>device\_type</code> и <code>device\_os</code> из файла mapping.</p><p>я знаю, как использовать dict, когда присутствуют только 2 столбца (необходимо сопоставить 1), но я не знаю, как этого добиться, когда нужно сопоставить 3 столбца.</p><p>ниже приведен код, с помощью которого я попытался выполнить сопоставление <code>device\_type</code>:</p><pre><code>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) </code></pre><p>возвращает <code>atribute error</code>.</p><p>после некоторого исследования я понял, что мне нужно создать вложенный дикт, но я не знаю, как это сделать. пожалуйста, помогите мне решить эту проблему или подтолкните меня в правильном направлении, чтобы решить эту проблему. </p>

<p>вложенный dict - это словарь в словаре. очень простая вещь.</p><pre><code>>>> d = {} >>> d['dict1'] = {} >>> d['dict1']['innerkey'] = 'value' >>> d {'dict1': {'innerkey': 'value'}} </code></pre><p>вы также можете использовать <a href="https://docs.python.org/2/library/collections.html#collections.defaultdict"><code>defaultdict</code></a> из пакета <a href="https://docs.python.org/2/library/collections.html"><code>collections</code></a> , чтобы упростить создание вложенных словарей.</p><pre><code>>>> 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'}} </code></pre><hr><p>вы можете заполнить это, как вы хотите.</p><p>я бы порекомендовал в вашем коде что-то <em>like</em> следующее:</p><pre><code>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 </code></pre><hr><p>согласно вашему <a href="https://stackoverflow.com/questions/16333296/how-do-you-create-nested-dict-in-python/16333441?noredirect=1#comment23400008\_16333441">комментарию</a> :</p><blockquote> <p>может быть, код выше запутывает вопрос. моя проблема в двух словах: я .\_\_ есть 2 файла a.csv b.csv, a.csv имеет 4 столбца i j k l, b.csv также имеет эти столбцы. я вроде ключевых столбцов для этих csv-файлов. j k l столбец пуст в a.csv, но заполнен в b.csv. я хочу отобразить значения j k l столбцы, использующие 'i` в качестве ключевого столбца из файла b.csv в файл a.csv</p> </blockquote><p>мое предложение будет что-то вроде <em>like</em> this (без использования defaultdict):</p><pre><code>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:])) </code></pre><p>обратите внимание, что для разбора csv-файлов существует модуль <a href="https://docs.python.org/2/library/csv.html">csv</a> .</p>

<p><strong>update</strong>: для произвольной длины вложенного словаря перейдите к <a href="https://stackoverflow.com/a/8702435/1757417">этот ответ</a> .</p><p>используйте функцию defaultdict из коллекций. </p><p>высокая производительность: «если ключ не в поле зрения» очень дорого, когда набор данных большой.</p><p>низкие эксплуатационные расходы: сделать код более читабельным и легко расширяемым.</p><pre><code>from collections import defaultdict target\_dict = defaultdict(dict) target\_dict[key1][key2] = val </code></pre>

<p>для произвольных уровней вложенности:</p><pre><code>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})})}) </code></pre>

<p>при использовании defaultdict и аналогичных вложенных модулей dict, таких как nested\_dict, важно помнить, что поиск несуществующего ключа может непреднамеренно создать новую запись ключа в dict и вызвать большой хаос. вот пример python3 с nested\_dict.</p><pre><code>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') </code></pre><p>результат:</p><pre><code>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 </code></pre>