Python - 为什么在映射两个列表时缩短了字典?

时间:2014-09-04 19:04:56

标签: python list dictionary

我有两个大的名单,相同的长度,每件2574件。我想将项目映射到字典中,因为在映射时,我想知道哪些值与其键不同。每个键一个值。然而,当我映射它们时,我会得到一个长度为76的短字典。

这是一个测试:

Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> list1 = [1, 1, 3, 4, 5, 6, 7, 8, 8, 8, 8, 8, 8, 10]
>>> list2 = [1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8, 8, 9, 10]
>>> 
>>> listdict = dict(zip(list1, list2))
>>> print len(list1)
14
>>> print len(list2)
14
>>> print len(listdict)
8
>>> print listdict
{1: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 9, 10: 10}

那么为什么使用dict(zip())会删除相互映射的1&1和将相互映射但保留其他所有内容的8?基本上,我的两个列表是相同的长度,并且对于每个索引,我需要知道项目是否不同。每个列表中用于比较的位置必须匹配。所以list1 [0]到list2 [0],而不是其他地方。当我拿到字典时,我认为这样的东西会起作用:

for k,v in listdict:
if k != v:
print k, '\t', v

但是他们没有匹配......

5 个答案:

答案 0 :(得分:2)

字典键必须唯一。只有最后一个1密钥存活,与上一个8密钥一样。

当您多次指定一个密钥时,只有一个(最后一个'处理过的)胜出

>>> {1: 1, 1: 2}
{1: 2}

如果您想知道哪些值与其键不同,请不要使用字典,只需收集不同的字符对:

different = [pair for pair in zip(list1, list2) if pair[0] != pair[1]]

您可以使用enumerate()

为此添加索引
different = [(i, pair) for i, pair in enumerate(zip(list1, list2)) if pair[0] != pair[1]]

演示:

>>> list1 = [1, 1, 3, 4, 5, 6, 7, 8, 8, 8, 8, 8, 8, 10]
>>> list2 = [1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8, 8, 9, 10]
>>> [pair for pair in zip(list1, list2) if pair[0] != pair[1]]
[(1, 2), (8, 9)]
>>> [(i, pair) for i, pair in enumerate(zip(list1, list2)) if pair[0] != pair[1]]
[(1, (1, 2)), (12, (8, 9))]

答案 1 :(得分:2)

正如其他答案所阐明的那样,dict要求密钥是唯一的。

听起来你更喜欢元组列表而不是字典。因此,请尝试以下操作:listdict = dict(zip(list1, list2))

,而不是listtup = list(zip(list1, list2))
>>> list1 = [1, 1, 3, 4, 5, 6, 7, 8, 8, 8, 8, 8, 8, 10]
>>> list2 = [1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8, 8, 9, 10]
>>> listtup = list(zip(list1, list2))
>>> listtup
[(1, 1), (1, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (8, 8), (8, 8), (8, 8), (8, 8), (8, 9), (10, 10)]

答案 2 :(得分:1)

dict将每个键映射到一个值。如果将相同的键多次设置为不同的值(或者当然是相同的值),则每个键都会覆盖前一个键。所以,例如:

>>> d = {}
>>> d[1] = 23
>>> d
{1: 23}
>>> d[1] = 69105
>>> d
{1: 69105}

如果你想为每个键存储多个值,你想要的是一个“multidict”,而不是一个dict。 Python内置了这样的东西,但使用defaultdict进行模拟很容易:

>>> import collections
>>> d = collections.defaultdict(set)
>>> d[1].add(23)
>>> d
{1: {23}}
>>> d[1].add(69105)
>>> d
{1: {69105, 23}}

所以,如果你想要一个从可迭代对中创建多重数据的函数,你可以很容易地写它:

def make_multidict(pairs):
    d = collections.defaultdict(set)
    for k, v in pairs:
        d[k].add(v)
    return d

答案 3 :(得分:1)

为了保留list1中的项目及其位置,请使用enumerate

>>> listdict = dict(zip(enumerate(list1), list2))
>>> listdict
{(0, 1): 1, (10, 8): 8, (6, 7): 7, (5, 6): 6, (7, 8): 8, (9, 8): 8, (13, 10): 10, (4, 5): 5, (8, 8): 8, (2, 3): 3, (11, 8): 8, (3, 4): 4, (1, 1): 2, (12, 8): 9}

listdict中的每个键都是一个元组,由list1的索引和该位置的项目组成。

答案 4 :(得分:0)

为了保留列表中元素的长度和顺序,请使用

OrderedDict(zip(list1,list2))