如何在Python列表中获取特定索引处的值?

6

我有一个列表,看起来像这样

List = [q1,a1,q2,a2,q3,a3]

我需要最终的代码类似于这样。
dictionary = {q1:a1,q2:a2,q3:a3}

如果我能获取特定索引处的值,比如List[0],我就可以完成这个任务,有没有办法获取它呢?

5个回答

11

可以使用dict类来构建Python字典,只需提供包含元组的可迭代对象即可。我们可以将其与内置的range函数结合使用,生成一个元组集合(每个奇数项,每个偶数项),并将其传递给dict函数,使值以键值对的形式在最终结果中组织:

dictionary = dict([(List[i], List[i+1]) for i in range(0, len(List), 2)])

2
您可以去掉 [],将列表解析改为生成器以获得更高的效率:dict((List[i], List[i+1]) for i in range(0, len(List), 2)) 这样,它不会生成一个列表,然后在转换为字典后将其丢弃。 - Chris Lutz
遇到了一个奇怪的错误。我在列表中有相同的值,例如[a,b,a,c,a,d]。输出只有唯一的值,例如[a:b]。我该如何解决这个问题? - Fahim Akhter
@zzzeek - 对于小列表来说,这可能更有效率,但对于大列表来说,它会死机。你可以在小规模情况下选择过度设计,或者在大规模情况下承受巨大的性能惩罚。你更愿意站在哪一边? - Chris Lutz
1
@Fahim,在字典中每个键只有一个值。也许你想要使用一个包含一个或多个值的列表作为键?这值得提出一个单独的问题! - Alex Martelli
1
是的,针对这个问题,你需要使用类似于{key: set([v1,v2,v3])}的结构。请提出一个新问题! - zzzeek
显示剩余4条评论

11

使用扩展切片符号:

dictionary = dict(zip(List[0::2], List[1::2]))

3

使用基于范围的答案更简单,但也可以使用itertools包来实现另一种方法:

from itertools import izip
dictionary = dict(izip(*[iter(List)] * 2))

将其拆分为以下几点(编辑:这次测试通过):

# Create instance of iterator wrapped around List
# which will consume items one at a time when called.
iter(List)

# Put reference to iterator into list and duplicate it so
# there are two references to the *same* iterator.
[iter(List)] * 2 

# Pass each item in the list as a separate argument to the
# izip() function.  This uses the special * syntax that takes
# a sequence and spreads it across a number of positional arguments.
izip(* [iter(List)] * 2)

# Use regular dict() constructor, same as in the answer by zzzeeek
dict(izip(* [iter(List)] * 2))

编辑: 感谢 Chris Lutz 的敏锐眼力进行了双重校正。


最后两行有错别字:没有结尾的] - Chris Lutz
现在你把它放错地方了。我想 iter(List) * 2 不是有效的方法。 - Chris Lutz

2
d = {}
for i in range(0, len(List), 2):
    d[List[i]] = List[i+1]

这正是我所想的,最简单和最好的选择。 :) - Fahim Akhter

0

你在评论中提到了有重复的条目。我们可以处理这个问题。选择你喜欢的生成元组列表的方法,并将其扩展为一个for循环:

from itertools import izip

dictionary = {}
for k, v in izip(List[::2], List[1::2]):
    if k not in dictionary:
        dictionary[k] = set()
    dictionary[k].add(v)

或者我们可以使用 collections.defaultdict,这样我们就不必检查键是否已经初始化:

from itertools import izip
from collections import defaultdict

dictionary = defaultdict(set)
for k, v in izip(List[::2], List[1::2]):
    dictionary[k].add(v)

我们最后使用一个字典,其中所有的键都是集合,而这些集合包含值。这仍然可能不太合适,因为像字典一样,集合也不能包含重复元素,所以如果你需要单个键来持有两个相同的值,那么你需要将其改为元组或列表。但这应该能帮助你入门。


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