从Python中的列表创建字典 - dict键省略列表中的相同项

时间:2018-02-05 16:38:07

标签: python python-3.x list dictionary

从列表中创建字典时,字典中的键忽略了列表中的相同项目,并将最后一项存储为键。

例如:

lst1 = [["Apple",20.00,"Swiss"],
    ["Banana",5.00,"Brazil"],
    ["Strawberry",25.00,"Swiss"],
    ["Pear",12.00,"Greece"],
    ["Mango",3.00,"Peru"],
    ["Avacado",7.00,"Peru"]]

my_dict = {val[2]:val[:2] for val in lst1}

print (my_dict)

打印此

{'Swiss': ['Strawberry', 25.0], 'Brazil': ['Banana', 5.0], 'Greece': ['Pear', 12.0], 'Peru': ['Avacado', 7.0]}

据我所知,因为密钥不能相同,所以为什么不将相同密钥的值分组到一个列表中。喜欢这个

{
    'Swiss': [["Apple",20.00],['Strawberry', 25.0]],
    'Brazil': ['Banana', 5.0],
    'Greece': ['Pear', 12.0],
    'Peru': [["Mango",3.00],['Avacado', 7.0]]
}

我有什么方法可以用纯Python做到这一点吗?

3 个答案:

答案 0 :(得分:4)

您无法使用字典理解,因此无法了解已存在的先前密钥。

您必须使用直接循环。将所有值添加到列表中,而不仅仅是重复值。不要在这里混合结构,以后只会产生更多的麻烦。如果你没有必要检测你是否有一个嵌套列表或一个含有一个水果和价格的平面列表。

您可以使用常规词典:

my_dict = {}
for fruit, price, origin in lst1:
    my_dict.setdefault(origin, []).append([fruit, price])

如果缺少键(第一个参数),dict.setdefault()调用会向字典添加一个空列表。然后它返回给定键的值(可以是已存在的列表或新的空列表)。然后该行调用list.append()添加水果和价格。

或者,当缺少密钥时,您可以使用collections.defaultdict() object创建空列表:

from collections import defaultdict

my_dict = defaultdict(list)
for fruit, price, origin in lst1:
    my_dict[origin].append([fruit, price])

使用defaultdict的代码更加简洁,但缺点是此对象现在将继续为缺失的密钥生成空列表,即使您可能由于某个bug而未打算这样做在你的代码中。

两者都产生了预期的结果:

>>> my_dict = {}
>>> for fruit, price, origin in lst1:
...     my_dict.setdefault(origin, []).append([fruit, price])
...
>>> my_dict
{'Swiss': [['Apple', 20.0], ['Strawberry', 25.0]], 'Brazil': [['Banana', 5.0]], 'Greece': [['Pear', 12.0]], 'Peru': [['Mango', 3.0], ['Avacado', 7.0]]}
>>> from collections import defaultdict
>>> my_dict = defaultdict(list)
>>> for fruit, price, origin in lst1:
...     my_dict[origin].append([fruit, price])
...
>>> my_dict
defaultdict(<class 'list'>, {'Swiss': [['Apple', 20.0], ['Strawberry', 25.0]], 'Brazil': [['Banana', 5.0]], 'Greece': [['Pear', 12.0]], 'Peru': [['Mango', 3.0], ['Avacado', 7.0]]})

答案 1 :(得分:3)

那种&#34;积累&#34;使用列表推导不能简单地解决问题(或者是丑陋的副作用会影响可读性)。

您希望collections.defaultdict(list)创建一对情侣列表作为值,将国家/地区作为关键字:

lst1 = [["Apple",20.00,"Swiss"],
    ["Banana",5.00,"Brazil"],
    ["Strawberry",25.00,"Swiss"],
    ["Pear",12.00,"Greece"],
    ["Mango",3.00,"Peru"],
    ["Avacado",7.00,"Peru"]]

result = collections.defaultdict(list)

for fruit,price,country in lst1:
    result[country].append([fruit,price])

print(dict(result))  # convert to dict for a cleaner representation when printing

结果:

{'Swiss': [['Apple', 20.0], ['Strawberry', 25.0]], 'Brazil': [['Banana', 5.0]], 'Greece': [['Pear', 12.0]], 'Peru': [['Mango', 3.0], ['Avacado', 7.0]]}

答案 2 :(得分:3)

据我所知,这不能在comprehension中完成,但您可以使用setdefault将每个列表的每个第二个元素设为lst1 a {{ 1}}在key中,您可以立即dictionary切片到达它(正如您所做的那样)。 append的整洁是我们可以追加setdefault(如果它已经存在),或创建key然后追加如果不是。这两项操作都是在没有key的情况下完成的。

if-statement

,并提供:

d = {}
for l in lst1:
    d.setdefault(l[2], []).append(l[:2])