Python根据键列表构建一个字典,并列出值列表

时间:2015-04-23 00:36:37

标签: python list dictionary

所以我有一个键列表:

keys = ['id','name', 'date', 'size', 'actions']

我还有一个vales列表列表:

values=
    [
        ['1','John','23-04-2015','0','action1'],
        ['2','Jane','23-04-2015','1','action2']
    ]

如何使用与值匹配的键构建字典?

输出应为:

{
    'id':['1','2'],
    'name':['John','Jane'],
    'date':['23-04-2015','23-04-2015'],
    'size':['0','1'],
    'actions':['action1','action2']
}

编辑: 我尝试使用zip()和dict(),但这只有在值列表有1个列表时才有效,即values = [['1','John','23-04-2015','0','action1']]

for list in values:
    dic = dict(zip(keys,list))

我还想过用键来初始化一个词组,然后自己建立一个值列表,但我觉得必须有一个更简单的方法来做。

dic = dict.fromkeys(keys)

for list in values:
    ids = list[0]
    names = list[1]
    dates = list[2]
    sizes = list[3]
    actions = list[4]

然后最后

dic['id'] = ids
dic['name'] = names
dic['date'] = dates
dic['size'] = sizes
dic['action'] = actions

这看起来真的很傻,我想知道更好的做法是什么。

1 个答案:

答案 0 :(得分:7)

>>> keys = ['id','name', 'date', 'size', 'actions']
>>> values = [['1','John','23-04-2015','0','action1'], ['2','Jane','23-04-2015','1','action2']]
>>> c = {x:list(y) for x,y in zip(keys, zip(*values))}
>>> c
{'id': ['1', '2'], 'size': ['0', '1'], 'actions': ['action1', 'action2'], 'date': ['23-04-2015', '23-04-2015'], 'name': ['John', 'Jane']}
>>> print(*(': '.join([item, ', '.join(c.get(item))]) for item in sorted(c, key=lambda x: keys.index(x))), sep='\n')
id: 1, 2
name: John, Jane
date: 23-04-2015, 23-04-2015
size: 0, 1
actions: action1, action2

这使用了几种工具:

使用字典理解创建

c。理解是表达像字典或列表这样的可迭代的不同方式。而不是初始化一个空的iterable,然后使用循环向其中添加元素,理解就会移动这些语法结构。

result = [2*num for num in range(10) if num%2]

相当于

result = []
for num in range(10):
    if num%2: # shorthand for "if num%2 results in non-zero", or "if num is not divisible by 2"
        result.append(2*num)

我们得到[2, 6, 10, 14, 18]

zip()创建一个元组生成器,其中每个元组的每个元素都是您传递给zip()的参数之一的对应元素。

>>> list(zip(['a','b'], ['c','d']))
[('a', 'c'), ('b', 'd')]

zip()有多个参数 - 如果你传递一个包含较小子列表的大型列表,结果就不同了:

>>> list(zip([['a','b'], ['c','d']]))
[(['a', 'b'],), (['c', 'd'],)]

通常不是我们想要的。但是,我们的values列表就是这样一个列表:包含子列表的大型列表。我们希望zip()这些子列表。现在是使用*运算符的好时机。

*运算符表示"已解压缩"可迭代。

>>> print(*[1,2,3])
1 2 3
>>> print(1, 2, 3)
1 2 3

它也用于函数定义:

>>> def func(*args):
...    return args
...
>>> func('a', 'b', [])
('a', 'b', [])

因此,要创建字典,我们将zip()值列在一起,然后使用键zip()。然后我们遍历每个元组并从中创建一个字典,每个元组的第一个项目是关键,第二个项目是值(转换为list而不是{{1 }})。

要打印这个,我们可以创建一个大的循环结构,或者我们可以创建生成器(比tuple之类的完整数据结构更快地组装和处理)并迭代它们,大量使用{{1解包东西。请记住,在Python 3中,list可以接受多个参数,如上所示。

我们将首先使用*中每个元素的位置作为关键字对字典进行排序。如果我们使用print之类的东西,它会将每个元素发送到keys函数并使用返回的长度作为键。我们使用key=len来定义一个内联的,未命名的函数,该函数在len()的{​​{1}}中获取参数lambdax s return的索引。 x。请注意,字典实际上并未排序;我们只是设置它,以便我们可以根据排序顺序迭代它。

然后我们可以浏览这个排序的字典并将其元素组合成可打印的字符串。在顶层,我们list一个密钥,其值由keys分隔。每个值的元素join()都带有': '。请注意,如果元素不是字符串,我们必须将它们转换为join()的字符串才能生效。

', '

然后使用join()运算符解包>>> list(map(str, [1,2,3])) ['1', '2', '3'] >>> print(*map(str, [1,2,3])) 1 2 3 每个yield ed行的生成器,并将每个元素作为参数发送到join(),指定*(新行)的分隔符,而不是默认的print()(空格)。

使用循环而不是理解和'\n'完全没问题,然后在逻辑运行后将它们重新排列成这样的结构,如果你愿意的话。在大多数情况下,这不是特别必要。理解有时比等效循环执行得稍快,并且通过练习,您可能更喜欢理解的语法。但是,要学习' '操作员 - 它是一个用于定义功能的极其通用的工具。另请查看*(通常称为"双星"或" kwargs"),它将字典解包为关键字参数,也可用于定义函数。