Я просматриваю целую кучу кортежей с коррекцией "многие ко многим", и я хочу сделать словарь, в котором каждый b (a, b) имеет список всех a, соответствующих значению b, Кажется неудобным проверять список в ключе b в словаре, а затем искать a, а затем добавлять, если он еще не существует, каждый раз через цикл переваривания кортежей; но я еще не нашел лучшего способа. Есть ли один? Есть ли другой способ сделать это намного красивее?
Эффективный способ создать список или добавить к нему, если он уже существует?
Ответ 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)