두 목록을 하나의 사전 목록에 매핑합니다
-
04-07-2019 - |
문제
이 파이썬 목록이 있다고 상상해보십시오.
keys = ['name', 'age']
values = ['Monty', 42, 'Matt', 28, 'Frank', 33]
다음 사전 목록을 생산하는 직접적이거나 간단한 방법이 있습니까?
[
{'name': 'Monty', 'age': 42},
{'name': 'Matt', 'age': 28},
{'name': 'Frank', 'age': 33}
]
해결책
여기에 zip way가 있습니다
def mapper(keys, values):
n = len(keys)
return [dict(zip(keys, values[i:i + n]))
for i in range(0, len(values), n)]
다른 팁
예쁘지는 않지만 여기에 목록 이해력, 지퍼 및 스텝핑을 사용하는 1 라이너가 있습니다.
[dict(zip(keys, a)) for a in zip(values[::2], values[1::2])]
바보 같은 길이지만 즉시 내 마음에 오는 것 :
def fields_from_list(keys, values):
iterator = iter(values)
while True:
yield dict((key, iterator.next()) for key in keys)
list(fields_from_list(keys, values)) # to produce a list.
zip
당신이 원하는 것을 거의 수행합니다. 불행히도, 짧은 목록을 순환하는 대신 깨집니다. 아마도 순환하는 관련 기능이 있습니까?
$ python
>>> keys = ['name', 'age']
>>> values = ['Monty', 42, 'Matt', 28, 'Frank', 33]
>>> dict(zip(keys, values))
{'age': 42, 'name': 'Monty'}
/편집 : 아, 당신은 a 목록 의 DITT. 다음 작품 (Peter에게도 감사합니다) :
from itertoos import cycle
keys = ['name', 'age']
values = ['Monty', 42, 'Matt', 28, 'Frank', 33]
x = zip(cycle(keys), values)
map(lambda a: dict(a), zip(x[::2], x[1::2]))
대답에 Konrad Rudolph
Zip은 원하는 것을 거의 수행합니다. 불행히도, 짧은 목록을 순환하는 대신 깨집니다. 아마도 순환하는 관련 기능이 있습니까?
방법은 다음과 같습니다.
keys = ['name', 'age']
values = ['Monty', 42, 'Matt', 28, 'Frank', 33]
iter_values = iter(values)
[dict(zip(keys, iter_values)) for _ in range(len(values) // len(keys))]
나는 그것을 Pythonic이라고 부르지 않을 것입니다 (너무 영리하다고 생각합니다). 그러나 그것이 찾고있는 것일 수도 있습니다.
자전거 타기에는 이점이 없습니다 keys
사용하는 목록 itertools
.cycle()
, 각각의 횡단 때문에 keys
하나의 사전의 생성에 해당합니다.
편집하다: 다른 방법은 다음과 같습니다.
def iter_cut(seq, size):
for i in range(len(seq) / size):
yield seq[i*size:(i+1)*size]
keys = ['name', 'age']
values = ['Monty', 42, 'Matt', 28, 'Frank', 33]
[dict(zip(keys, some_values)) for some_values in iter_cut(values, len(keys))]
이것은 훨씬 더 피스닉입니다. 명확한 목적을 가진 읽을 수있는 유틸리티 기능이 있으며 나머지 코드는 자연스럽게 흐릅니다.
여기 내 간단한 접근 방식이 있습니다. 입력 목록을 파괴한다는 점을 제외하고는 @cheery가 가지고 있었다는 생각에 가깝습니다.
def pack(keys, values):
"""This function destructively creates a list of dictionaries from the input lists."""
retval = []
while values:
d = {}
for x in keys:
d[x] = values.pop(0)
retval.append(d)
return retval
또 다른 시도, 아마도 첫 번째 시도보다 멍청 할 것입니다.
def split_seq(seq, count):
i = iter(seq)
while True:
yield [i.next() for _ in xrange(count)]
>>> [dict(zip(keys, rec)) for rec in split_seq(values, len(keys))]
[{'age': 42, 'name': 'Monty'},
{'age': 28, 'name': 'Matt'},
{'age': 33, 'name': 'Frank'}]
그러나 그것이 멍청한지를 결정하는 것은 당신에게 달려 있습니다.
[dict(zip(keys,values[n:n+len(keys)])) for n in xrange(0,len(values),len(keys)) ]
UG-LEEE. 나는 그렇게 보이는 코드를보고 싶지 않습니다. 그러나 그것은 옳게 보입니다.
def dictizer(keys, values):
steps = xrange(0,len(values),len(keys))
bites = ( values[n:n+len(keys)] for n in steps)
return ( dict(zip(keys,bite)) for bite in bites )
여전히 조금 못 생겼지 만 이름은 이해하는 데 도움이됩니다.