Словари в Python - PullRequest
       28

Словари в Python

5 голосов
/ 10 марта 2009

Я пытаюсь ускорить использование словарей. Вчера вечером я потратил три часа на поиск в Интернете примеров, похожих на некоторые вещи, которые я пытаюсь сделать. Например, предположим, у меня есть два словаря (на самом деле у меня есть два списка словарей).

d1={key1:1, key2:2}
d2={key1:1, key2:'A', key4:4}

Я хочу обновить d1, чтобы он выглядел следующим образом:

d1={key1:1, key2:[2,'A'], key3:3, key4:4}

Кажется, я не могу найти адекватных примеров, чтобы начать меня. У меня есть достаточное количество книг, и я также рецензировал их, но у них, похоже, есть примеры того же типа, которые я нахожу в Интернете.

Кто-нибудь знает место или книгу, в которой есть явные примеры и описания использования словарей?

Я думаю, что одна из проблем, с которыми я сталкиваюсь, заключается в том, что я не понимаю, как поддерживаются ссылки при доступе к словарю.

Я могу проверить, есть ли у двух словарей общий ключ:

for k in d1.keys():
    for k2 in d2.keys():
        if k==k2:
            print 'true'

но если они это сделают, я не могу объединить значения в список.

Более, чем прямой ответ на этот конкретный пример, я был бы признателен за любые предложения о местах, где есть хорошие примеры использования словарей.

Ответы [ 9 ]

13 голосов
/ 10 марта 2009

Попробуйте это:

import collections
merged = collections.defaultdict(list)
for k in d1:
   merged[k].append( d1[k] )
for k in d2:
   merged[k].append( d2[k] )

Это может быть то, что вы ищете.

Или, возможно, это.

import collections
merged = collections.defaultdict(set)
for k in d1:
   merged[k].add( d1[k] )
for k in d2:
   merged[k].add( d2[k] )
6 голосов
/ 10 марта 2009

Хорошее начало - это получить iPython (easy_install ipython), а затем возиться с завершением табуляции, ? и dir:

In [2]: dir {}
------> dir({})

Out[2]: 
['__class__',
 ...
 'keys',
 'pop',
 'popitem',
 'setdefault',
 'update',
 'values']

In [3]: {}.update?
Type:       dict
Base Class: <type 'dict'>
String Form:    {}
Namespace:  Interactive
Length:     0
Docstring:
    dict() -> new empty dictionary.
    dict(mapping) -> new dictionary initialized from a mapping object's
        (key, value) pairs.
    dict(seq) -> new dictionary initialized as if via:
        d = {}
        for k, v in seq:
            d[k] = v
    dict(**kwargs) -> new dictionary initialized with the name=value pairs
        in the keyword argument list.  For example:  dict(one=1, two=2)

(только для примера)

В любом случае, ваша проблема с проверкой ключей, общих для двух словарей: есть несколько вещей, на которые следует обратить внимание (возможно, посмотрите на класс set?), Но вот как я это сделаю:

common_keys = [k for k in dict1 if k in dict2]

(т. Е. «Каждый ключ k в dict1, если этот ключ также находится в dict2») (также обратите внимание, что проверка на членство в словаре является операцией O (1), поэтому она будет выполняться в O (| dict1 |))

edit : хорошо, так что это не решает проблему объединения двух диктов в один со списками ... Но ответ Лотта хорош для этого, или вы можете использовать метод setdefault :

new = {}
for (k, v) in dict1.items():
    new.setdefault(k, []).append(v)
for (k, v) in dict2.items():
    new.setdefault(k, []).append(v)
4 голосов
/ 10 марта 2009

Мне кажется, вот что вы хотите:

>>> d1={'key1':1, 'key2':2}
>>> d2={'key1':1, 'key2':'A', 'key4':4}
>>> d = {}
>>> d.update(d1)
>>> for i in d2:
        if i in d and d2[i] != d[i]:
            d[i] = [d[i], d2[i]]
        else:
            d[i] = d2[i]            
>>> d
{'key2': [2, 'A'], 'key1': 1, 'key4': 4}
2 голосов
/ 10 марта 2009
1 голос
/ 10 марта 2009

Словари Python также очень похожи на ассоциативные массивы в PHP, если у вас есть опыт работы с этим языком.

На странице «Встроенные типы» в документации по Python также есть хороший раздел о словарях, и в разделе также есть список доступных для них функций:

http://docs.python.org/library/stdtypes.html#mapping-types-dict

0 голосов
/ 23 февраля 2010

Вот еще один вариант.

d1 = {'key1'=1, 'key2'=2}
d2 = {'key1'=1, 'key2'='A', 'key4'=4)
d = d2
for k, v in d.iteritems():
... if k in d1.keys() and v!=d1[k]:
... d[k] = [d1[k], v2]
d
{'key2': [2, 'A'], 'key1': 1, 'key4': 4}
0 голосов
/ 11 марта 2009

Возможно, это немного неловко, потому что структура данных, которую вы пытаетесь создать, не так естественна, как могла бы быть. Например, вместо того, чтобы некоторые значения были одиночными, а некоторые - списками, почему бы не сохранить все в списках? Э.Г.

{'key1': [1], 'key2': [2, 'A'], 'key4': [4]}

В Python возможно иметь коллекцию смешанных типов данных, но ваш код часто будет чище, если вы будете поддерживать его согласованным. Если вы используете такую ​​структуру данных, вставка будет такой же простой, как

# Inserting a (key, value) pair
if key in my_dict:
    my_dict[key].append(value)
else:
    my_dict[key] = [value]
0 голосов
/ 10 марта 2009

Вариация @ ответа SilentGhost (все остальные ответы приводят к неправильным словарям):

>>> d1 = dict(key1=1, key2=2)
>>> d2 = dict(key1=1, key2='A', key4=4)
>>> d = dict(d1)
>>> for k, v2 in d2.iteritems():
...     v = d.get(k, None)
...     d[k] = [v, v2] if v is not None and v != v2 else v2
...
>>> d
{'key2': [2, 'A'], 'key1': 1, 'key4': 4}
0 голосов
/ 10 марта 2009

ну, для вашего первого случая вам может понадобиться помощник, который объединяет два объекта в список из двух объектов и два списка в один список, содержащий элементы из двух списков,

Конечно, это предполагает, что вы всегда объединяете ключи в списки, но не хотите, чтобы ваши ключи в конечном итоге превратились в "списки списков"

def listify( obj ): 
   if type(obj) != type([]): return [obj]
   else: return obj

def merge( v1, v2 ):
    return listify(v1) + listify(v2)

#so now you can merge two dictionaries:
dict1 = dict(a = 2, b = 5, c = 7 )
dict2 = dict(b = 4, d = 9, f = 10 )
dikt = {}

for k in set( dict1.keys() + dict2.keys() ):
    dikt[k] = merge( dict1.get(k, []), dict2.get(k, []) )
#resutls in:
# {'a': [2], 'c': [7], 'b': [5, 4], 'd': [9], 'f': [10]}

Вы можете заметить, dict.keys() возвращает список ключей, set возвращает список без дубликатов, поэтому set( d1.keys(), d2.keys() ) возвращает объединение ключей d1 и d2

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...