将三个列表合并为一个字典

5

我需要将三个列表合并为一个字典。这些列表来自我格式化的txt文件,以下是该文件的一部分内容:

maker =['Horsey', 'Ford', 'Overland', 'Scripps-Booth']

year = ['1899', '1909', '1911', '1913']

model = ['Horseless', 'Model T', 'OctoAuto', 'Bi-Autogo']

Into the following:

car_dict = {'Horsey':1899,'Horseless','Ford':1909,'Model T','Overland' : 1911, 'OctoAuto', 'Scripps-Booth' : 1913, 'Bi-Autogo'}

这是我所做的:

def car_data_merge(car_maker,car_model,car_year):
    car_dict = {}
    car_merge = []

    car_dict = defaultdict(partial(defaultdict,list))

    for (car_maker,car_model,car_year) in zip(car_maker,car_model,car_year):
         car_dict[car_year][car_model].append(car_maker)
    print(car_dict)

当我输入这个时,我得到了:
{'Horsey': defaultdict(<class 'list'>, {'1899': ['Horseless']})

并非所有列表数据都显示,而且我不想显示 defaultdict

当我尝试以下操作时:

def car_data_merge(car_maker,car_data):
    car_dict = {}
    car_merge = []
    car_merge = zip(car_maker,car_data)  
    car_dict = dict(car_merge)
    print(car_dict)

    ###   car_data holds both year and model   ####

仅部分数据显示:

'Horsey':'Horseless',':1909,'Model T

我该怎么办?

4个回答

9
你使用 zip 是正确的,但要注意以下几点:

返回的列表长度被截断为最短的参数序列的长度。

如果你可以接受这一点,你可以将数据压缩成元组列表,将键压缩,并将所有内容交给 dict()
如果你想处理缺失值,请查看 itertools 中的izip_longest(Python 2)zip_longest(Python 3),其中

如果可迭代对象的长度不相等,则使用fillvalue填充缺少的值。

try:
    # Python 2
    from itertools import izip_longest
    zip_longest = izip_longest
except ImportError:
    # Python 3
    from itertools import zip_longest

from pprint import pprint


def main():
    maker =['Horsey', 'Ford', 'Overland', 'Scripps-Booth', 'FutureX', 'FutureY']
    year = ['1899', '1909', '1911', '1913', '20xx']
    model = ['Horseless', 'Model T', 'OctoAuto', 'Bi-Autogo']

    car_data = dict(zip(maker, zip(year, model)))
    car_data_longest = {mk: (yr, md) for mk, yr, md in zip_longest(maker, year, model)}

    pprint(car_data)
    pprint(car_data_longest)

输出:

{'Ford': ('1909', 'Model T'),
 'Horsey': ('1899', 'Horseless'),
 'Overland': ('1911', 'OctoAuto'),
 'Scripps-Booth': ('1913', 'Bi-Autogo')}
{'Ford': ('1909', 'Model T'),
 'FutureX': ('20xx', None),
 'FutureY': (None, None),
 'Horsey': ('1899', 'Horseless'),
 'Overland': ('1911', 'OctoAuto'),
 'Scripps-Booth': ('1913', 'Bi-Autogo')}

问题:我以前从未使用过izip,但我得到了values = itertools.izip(year, model) AttributeError: 'module' object has no attribute 'izip',我该怎么办? - Thomas Jones
@ThomasJones 这是 izip_longest - pradyunsg
@ThomasJones 你使用的 Python 版本是多少?itertools.izip 在 Python 2.3 中被添加,且在 Python 2.4 中进行了修改。itertools.izip_longest 是 Python 2.6 中新增的。 - Stephen Norum
我正在使用Python 3.3.0,我刚下载了2.6版本,它可以工作。谢谢!另外,有没有办法在Python 3.3.0中使用? - Thomas Jones
啊,说得好。在Python 3中,zip()已经返回一个迭代器。itertools.izip_longest也变成了itertools.zip_longest。http://docs.python.org/3/library/functions.html#zip,http://docs.python.org/3.3/library/itertools.html#itertools.zip_longest - Stephen Norum
谢谢你!这是我在打印字典时遇到的一个主要问题之一。除非每一行都一样,否则字典会被错误地打印出来。你是第一名! - Thomas Jones

8
这个怎么样:
>>> maker =['Horsey', 'Ford', 'Overland', 'Scripps-Booth']
>>> year = ['1899', '1909', '1911', '1913']
>>> model = ['Horseless', 'Model T', 'OctoAuto', 'Bi-Autogo']
>>> d = dict(zip(maker,zip(year,model)))
{'Overland': ('1911', 'OctoAuto'), 'Horsey': ('1899', 'Horseless'), 'Scripps-Booth': ('1913', 'Bi-Autogo'), 'Ford': ('1909', 'Model T')}

你不需要调用 list。Zip 会创建一个元组列表,从中你可以创建一个字典。 - Abhijit
有人对这个答案进行了负评,他们能否澄清一下原因? - TerryA

3

听起来你想要的是:

{maker: (year, model) for maker, model, year in zip(car_maker,car_model,car_year)}

这将会给您带来:
{'Horsey':(1899,'Horseless'),'Ford':(1909,'Model T'),'Overland':(1911,'OctoAuto')...}

2

这是你正在寻找的类型吗?

>>> car_dict = {maker[i]:[year[i], model[i]] for i in xrange(len(maker))}
>>> car_dict
{'Overland': ['1911', 'OctoAuto'], 'Horsey': ['1899', 'Horseless'], 'Scripps-Booth': ['1913', 'Bi-Autogo'], 'Ford': ['1909', 'Model T']}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接