딕셔너리 목록과의 딕셔너리 목록
목록 사전 (모두 길이가 같음)간에 앞뒤로 변경하려고합니다.
DL = {'a': [0, 1], 'b': [2, 3]}
및 사전 목록 :
LD = [{'a': 0, 'b': 2}, {'a': 1, 'b': 3}]
두 가지 양식을 전환하는 가장 깨끗한 방법을 찾고 있습니다.
아마도 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 = {k: [dic[k] for dic in LD] for k in LD[0]}
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]}
다른 길로가는 것은 문제가됩니다. 사전의 키에서 목록에 삽입 순서 정보가 있어야합니다. 딕셔너리의 키 순서가 원래 삽입 순서와 반드시 동일하지는 않습니다.
웃음의 경우 삽입 순서가 정렬 된 키를 기반으로한다고 가정합니다. 그런 다음 다음과 같이 할 수 있습니다.
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]}
그런 다음이를 사전 목록으로 변환하는 방법은 다음과 같습니다.
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 3 대신 Python 2를 사용 reduce
하는 경우 대신 사용할 수 있습니다 functools.reduce
.
목록의 모든 사전에 동일한 키가 있다고 가정하면이를 단순화 할 수 있습니다.
dl2 = {key:[item[key] for item in ld] for key in ld[0].keys() }
cytoolz.dicttoolz.merge_with
from cytoolz.dicttoolz import merge_with
merge_with(list, *LD)
{'a': [0, 1], 'b': [2, 3]}
비 Cython 버전
from toolz.dicttoolz import merge_with
merge_with(list, *LD)
{'a': [0, 1], 'b': [2, 3]}
의 python 모듈은 pandas
이해하기 쉬운 솔루션을 제공 할 수 있습니다. @chiang의 대답을 보완하기 위해 D-to-L 및 L-to-D의 솔루션은 다음과 같습니다.
In [1]: import pandas as pd
In [2]: DL = {'a': [0, 1], 'b': [2, 3]}
In [3]: pd.DataFrame(DL).to_dict('records')
Out[3]: [{'a': 0, 'b': 2}, {'a': 1, 'b': 3}]
In [4]: LD = [{'a': 0, 'b': 2}, {'a': 1, 'b': 3}]
In [5]: pd.DataFrame(LD).to_dict('list')
Out[5]: {'a': [0, 1], 'b': [2, 3]}
여기 내 작은 스크립트 :
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) 목록 길이가 같다고 가정합니다.
내가 여름 금요일을 생각할 수있는 가장 깨끗한 방법. 보너스로 길이가 다른 목록을 지원합니다 (이 경우 DLtoLD(LDtoDL(l))
더 이상 신원이 아닙니다).
목록에서 dict로
@dwerk의 defaultdict 버전보다 실제로 덜 깨끗합니다.
def LDtoDL (l) : result = {} for d in l : for k, v in d.items() : result[k] = result.get(k,[]) + [v] #inefficient return result
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
다음은 라이브러리를 사용하지 않는 솔루션입니다.
def dl_to_ld(initial):
finalList = []
neededLen = 0
for key in initial:
if(len(initial[key]) > neededLen):
neededLen = len(initial[key])
for i in range(neededLen):
finalList.append({})
for i in range(len(finalList)):
for key in initial:
try:
finalList[i][key] = initial[key][i]
except:
pass
return finalList
다음과 같이 호출 할 수 있습니다.
dl = {'a':[0,1],'b':[2,3]}
print(dl_to_ld(dl))
#[{'a': 0, 'b': 2}, {'a': 1, 'b': 3}]
발전기가 마음에 들지 않으면 다음과 같은 것을 사용할 수 있습니다.
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
It's not as "clean" as it could be for Technical Reasons: My original implementation did yield dict(...)
, but this ends up being the empty dictionary because (in Python 2.5) a for b in c
does not distinguish between a StopIteration exception when iterating over c
and a StopIteration exception when evaluating a
.
On the other hand, I can't work out what you're actually trying to do; it might be more sensible to design a data structure that meets your requirements instead of trying to shoehorn it in to the existing data structures. (For example, a list of dicts is a poor way to represent the result of a database query.)
DL={'a':[0,1,2,3],'b':[2,3,4,5]}
LD=[{'a':0,'b':2},{'a':1,'b':3}]
Empty_list = []
Empty_dict = {}
# to find length of list in values of dictionry
len_list = 0
for i in DL.values():
if len_list < len(i):
len_list = len(i)
for k in range(len_list):
for i,j in DL.items():
Empty_dict[i] = j[k]
Empty_list.append(Empty_dict)
Empty_dict = {}
LD = Empty_list
ReferenceURL : https://stackoverflow.com/questions/5558418/list-of-dicts-to-from-dict-of-lists
'program story' 카테고리의 다른 글
Scala의 증분 (++) 연산자 (0) | 2021.01.07 |
---|---|
System.Net.Mail을 사용하여 Gmail을 통해 이메일 보내기 (0) | 2021.01.07 |
bash : 백그라운드 함수 프로세스를 조용히 종료 (0) | 2021.01.07 |
Uri에 대한 Android URL (0) | 2021.01.07 |
Python을 사용하여 RGB 색상을 'green'과 같은 영어 색상 이름으로 변환 (0) | 2021.01.07 |