Подтвердить что ты не робот

Эффективный способ создать список или добавить к нему, если он уже существует?

Я просматриваю целую кучу кортежей с коррекцией "многие ко многим", и я хочу сделать словарь, в котором каждый b (a, b) имеет список всех a, соответствующих значению b, Кажется неудобным проверять список в ключе b в словаре, а затем искать a, а затем добавлять, если он еще не существует, каждый раз через цикл переваривания кортежей; но я еще не нашел лучшего способа. Есть ли один? Есть ли другой способ сделать это намного красивее?

4b9b3361

Ответ 1

Смотрите документы для метода setdefault():

setdefault (ключ [, по умолчанию])
Если ключ в словаре вернет свое значение. Если нет, введите ключ со значением default и return default. по умолчанию по умолчанию - None.

Вы можете использовать это как один вызов, который получит b, если он существует, или установите b в пустой список, если он еще не существует - и в любом случае, return b:

>>> key = 'b'
>>> val = 'a'
>>> print d
{}
>>> d.setdefault(key, []).append(val)
>>> print d
{'b': ['a']}
>>> d.setdefault(key, []).append('zee')
>>> print d
{'b': ['a', 'zee']}

Объедините это с простой проверкой "не в", и вы сделали то, что вам нужно, в трех строках:

>>> b = d.setdefault('b', [])
>>> if val not in b:
...   b.append(val)
... 
>>> print d
{'b': ['a', 'zee', 'c']}

Ответ 2

Предполагая, что вы не привязаны к спискам, defaultdict и set весьма удобны.

import collections
d = collections.defaultdict(set)
for a, b in mappings:
    d[b].add(a)

Если вам действительно нужны списки вместо наборов, вы можете следовать этому с помощью

for k, v in d.iteritems():
    d[k] = list(v)

И если вы действительно хотите использовать dict вместо defaultdict, вы можете сказать

d = dict(d)

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

Ответ 3

Использовать collections.defaultdict

your_dict = defaultdict(list)
for (a,b) in your_list:
    your_dict[b].append(a)

Ответ 4

Вместо использования if, AFAIK более pythonic использует вместо этого блок try.

your_list=[('a',1),('a',3),('b',1),('f',1),('a',2),('z',1)]

your_dict={}
for (a,b) in your_list:
    try:
        your_dict[b].append(a)
    except KeyError:
        your_dict[b]=[a]

print your_dict

Ответ 5

вы можете отсортировать свои кортежи O (n log n), затем создать словарь O (n)

или проще O (n), но может наложить большую нагрузку на память в случае множества кортежей:

your_dict = {}
for (a,b) in your_list:
    if b in your_dict:
        your_dict[b].append(a)
    else:
        your_dict[b]=[a]

Хм, это почти так же, как вы описали. Что неудобно в этом?

Вы также можете рассмотреть возможность использования базы данных sql для выполнения грязной работы.

Ответ 6

Я не уверен, как вы выйдете из теста ключей, но как только пара ключей/значений была инициализирована, это легко:)

d = {}
if 'b' not in d:
  d['b'] = set()
d['b'].add('a')

Набор гарантирует, что в коллекции будет только 1 из 'a'. Вам нужно выполнить начальную проверку "b", хотя убедитесь, что ключ/значение существует.

Ответ 7

Dict get метод? Он возвращает значение my_dict[some_key], если some_key находится в словаре, а если нет - возвращает значение по умолчанию ([] в примере ниже):

my_dict[some_key] = my_dict.get(some_key, []).append(something_else)