Python: при использовании метода Dictionary для возврата пустого списка по умолчанию возвращается None! - PullRequest
11 голосов
/ 24 апреля 2011

В Python я хотел бы создать словарь массивов, используя метод словаря get, чтобы по умолчанию предоставить пустой список, чтобы затем заполнить информацией, например ::

dict = {}
for i in range( 0, 10 ):
    for j in range( 0, 100 ):
        dict[i] = dict.get( i, [] ).append( j )

Однако, когда я пробую приведенный выше код, я не получаю никаких исключений, но мой список заканчивается следующим образом:

AttributeError: объект 'NoneType' не имеет атрибута 'append'

В списках есть метод добавления, поэтому я упростил свой тест до следующего:

dict = {}
for i in range( 0, 10 ):
    dict[i] = dict.get( i, [] ).append( i )

И результат был следующий:

{0: нет, 1: нет, 2: нет, 3: нет, 4: нет, 5: нет, 6: нет, 7: нет, 8: нет, 9: нет}

Итак, мой вопрос: почему dict.get (i, []) возвращает None по умолчанию, а не []? Выполнение dict.get (i, list ()) имеет ту же проблему, поэтому я немного озадачен.

Ответы [ 5 ]

18 голосов
/ 24 апреля 2011

Для решения этой проблемы вам нужно использовать Python's defaultdict.

http://docs.python.org/library/collections.html#defaultdict-examples

from collections import defaultdict 

dict = defaultdict(list)
for i in range( 0, 10 ):
    for j in range( 0, 100 ):
        dict[i].append( j )
17 голосов
/ 24 апреля 2011

Это не dict.get( i, [] ), которое возвращает None, это append. Вы, вероятно, хотите использовать dict.setdefault(i, []).append(j) или просто использовать defaultdict.

Вот как бы вы это сделали:

d = {}
for i in range( 0, 10 ):
    for j in range( 0, 100 ):
        d.setdefault( i, [] ).append( j )

Обратите внимание, что я изменил dict на d, потому что dict уже означает что-то в Python (вы переопределяете это), и я удалил лишнее dict[i] =, которое вызывало сообщение об ошибке.

3 голосов
/ 24 апреля 2011

Проблема в том, что append возвращает None вместо объекта списка.Так что

dict[i] = dict.get( i, [] ).append( j ) присваивает None для dict[i]

Однако вы можете сделать намного проще:

dict.setdefault( i, [] ).append( j )

.. цитируя документы для setdefault:

Если ключ находится в словаре, вернуть его значение.Если нет, вставьте ключ со значением по умолчанию и верните значение по умолчанию

Так, если ключ i еще не существует, он создает его и сохраняет в нем значение по умолчанию, в любом случае он возвращаетЗначение ключа - это ссылка на список, поэтому вы можете изменить его напрямую.

2 голосов
/ 24 апреля 2011

append не возвращает список.Добавляет значение в список и возвращает None.

Вместо этого:

 dict[i] = dict.get( i, [] ).append( j ) 

Вы можете сделать это:

 dict.setdefault(i, [])
 dict[i].append( j )
1 голос
/ 21 мая 2013

Альтернатива, которая использует метод get, используя преимущества добавления списка.

d = {}
for i in range(0, 10):
    for j in range(0, 100):
        d[i] = d.get(i, []) + [j]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...