список dicts в / из dict списков

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

DL={'a':[0,1],'b':[2,3]} 

и список словарей:

 LD=[{'a':0,'b':2},{'a':1,'b':3}] 

Я ищу самый чистый способ переключения между двумя формами.

  • Передача информации об аутентификации apache2 в скрипт wsgi, выполняемый mod_wsgi
  • Очистка модулей Python и запуск Mac OS X
  • слои keras toturial и образцы
  • `pip install pandas` дает UnicodeDecodeError: кодек ascii не может декодировать байт 0xe2 в позиции 41: порядковый номер не в диапазоне (128)
  • Как я могу подключиться к локальной базе данных преимуществ, используя pyodbc в python?
  • Python - re.findall возвращает нежелательный результат
  • Как использовать параметр «count» в потоковом API tweepy?
  • Метод sort () Python в списке vs встроенная функция sorted ()
  • 8 Solutions collect form web for “список dicts в / из dict списков”

    Возможно, рассмотрите использование numpy:

     import numpy as np arr=np.array([(0,2),(1,3)],dtype=[('a',int),('b',int)]) print(arr) # [(0, 2) (1, 3)] 

    Здесь мы обращаемся к столбцам, индексированным по именам, например 'a' или 'b' (вроде DL ):

     print(arr['a']) # [0 1] 

    Здесь мы обращаемся к строкам с помощью целочисленного индекса (вроде LD ):

     print(arr[0]) # (0, 2) 

    К каждому значению в строке можно обращаться по имени столбца (вроде LD ):

     print(arr[0]['b']) # 2 

    Для тех из вас, кто пользуется умными / взломанными однострочниками.

    Вот DL для LD :

     v = [dict(zip(DL,t)) for t in zip(*DL.values())] print(v) 

    и LD для DL :

     v = dict(zip(LD[0],zip(*[d.values() for d in LD]))) print(v) 

    LD to DL – маленький хакер, поскольку вы предполагаете, что ключи одинаковы в каждом dict . Кроме того, обратите внимание, что я не рекомендую использовать такой код в любой реальной системе.

    Чтобы перейти из списка словарей, это просто:

    Вы можете использовать эту форму:

     DL={'a':[0,1],'b':[2,3], 'c':[4,5]} LD=[{'a':0,'b':2, 'c':4},{'a':1,'b':3, 'c':5}] nd={} for d in LD: for k,v in d.items(): try: nd[k].append(v) except KeyError: nd[k]=[v] print nd #{'a': [0, 1], 'c': [4, 5], 'b': [2, 3]} 

    Или используйте defaultdict :

     nd=cl.defaultdict(list) for d in LD: for key,val in d.items(): nd[key].append(val) print dict(nd.items()) #{'a': [0, 1], 'c': [4, 5], 'b': [2, 3]} 

    Другое дело – проблематично. Вы должны иметь некоторую информацию о порядке вставки в списке из ключей из словаря. Напомним, что порядок ключей в dict не обязательно совпадает с порядком ввода.

    Для хихиканья предположим, что порядок вставки основан на отсортированных клавишах. Вы можете сделать это следующим образом:

     nl=[] nl_index=[] for k in sorted(DL.keys()): nl.append({k:[]}) nl_index.append(k) for key,l in DL.items(): for item in l: nl[nl_index.index(key)][key].append(item) print nl #[{'a': [0, 1]}, {'b': [2, 3]}, {'c': [4, 5]}] 

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

    Если вам разрешено использовать внешние пакеты, Pandas отлично подходит для этого:

     import pandas as pd pd.DataFrame(DL).to_dict('list') 

    Какие результаты:

     [{'a': 0, 'b': 2}, {'a': 1, 'b': 3}] 

    Вот однолинейные решения (разбросанные по нескольким строкам для удобочитаемости), которые я придумал:

    если dl – ваш оригинальный список списков:

     dl = {"a":[0,1],"b":[2,3]} 

    Затем вот как преобразовать его в список dicts:

     ld = [{key:value[index] for key in dl.keys()} for index in range(max(map(len,dl.values()] 

    Который, если вы предполагаете, что все ваши списки имеют одинаковую длину, вы можете упростить и увеличить производительность, перейдя к:

     ld = [{key:value[index] for key, value in dl.items()} for index in range(len(dl.values()[0]))] 

    и вот как преобразовать это обратно в диктовку списков:

     dl2 = {key:[item[key] for item in ld] for key in list(functools.reduce( lambda x, y: x.union(y), (set(dicts.keys()) for dicts in ld) )) } 

    Если вы используете Python 2 вместо Python 3, вы можете просто использовать reduce вместо functools.reduce there.

    Вы можете упростить это, если предположите, что все диктофоны в вашем списке будут иметь одинаковые ключи:

     dl2 = {key:[item[key] for item in ld] for key in ld[0].keys() } 

    Вот мой маленький скрипт:

     a = {'a': [0, 1], 'b': [2, 3]} elem = {} result = [] for i in a['a']: # (1) for key, value in a.items(): elem[key] = value[i] result.append(elem) elem = {} print result 

    Я не уверен, что это прекрасный способ.

    (1) Вы полагаете, что у вас одинаковая длина для списков

    Если вы не возражаете против генератора, вы можете использовать что-то вроде

     def f(dl): l = list((k,v.__iter__()) for k,v in dl.items()) while True: d = dict((k,i.next()) for k,i in l) if not d: break yield d 

    Это не так «чисто», как это могло бы быть из-за технических причин: моя первоначальная реализация yield dict(...) , но в конечном итоге это пустой словарь, потому что (в Python 2.5) a for b in c не различает Исключение StopIteration при итерации по c и исключение StopIteration при оценке a .

    С другой стороны, я не могу понять, что вы на самом деле пытаетесь сделать; возможно, было бы более разумно проектировать структуру данных, которая соответствует вашим требованиям, вместо того, чтобы пытаться привязать ее к существующим структурам данных. (Например, список dicts – это плохой способ представления результата запроса базы данных.)

    Самый чистый способ я могу думать о летней пятнице. В качестве бонуса он поддерживает списки разной длины (но в этом случае DLtoLD(LDtoDL(l)) больше не идентичен).

    1. Из списка в диктофон

      На самом деле менее чистая, чем версия dderk по умолчанию.

       def LDtoDL (l) : result = {} for d in l : for k, v in d.items() : result[k] = result.get(k,[]) + [v] #inefficient return result 
    2. От dict до списка

       def DLtoLD (d) : if not d : return [] #reserve as much *distinct* dicts as the longest sequence result = [{} for i in range(max (map (len, d.values())))] #fill each dict, one key at a time for k, seq in d.items() : for oneDict, oneValue in zip(result, seq) : oneDict[k] = oneValue return result 
    Python - лучший язык программирования в мире.