python 单行初始化字典

Python oneliner to initialize a dictionary

本问题已经有最佳答案,请猛点这里访问。

我正在寻找一个简短而紧凑的一行程序来从Python中的列表初始化字典。下面的两个结构是否等价?

1
2
3
dic = {}
for elt in list:
  dic[elt.hash] = elt

.

1
2
3
4
dic2 = {}
defaultValue = 0
for elt in list:
  dic2[elt] = defaultValue

我已经看到在第二种情况下使用Counter,但这是一个非常狭窄的情况,我正在寻找通用语法。


嗯,字典理解是一行,这就是你的意思吗?

1
2
3
4
5
6
>> MyList = ['apple', 'banana', 'pear']
>> {hash(element): element for element in MyList}

{-8723846192743330971: 'pear',
 -6060554681585566095: 'banana',
 -4133088065282473265: 'apple'}

另外-我怀疑使用元素的哈希作为键不是您要查找的:

  • 如果元素是不可变的(例如字符串),则可以将元素本身用作键。
  • 如果它们不是不变的,则可以使用元素在列表中的位置。

对于后者,为了确保每个值只插入一次到dict,请在迭代之前清除列表中的重复项:

1
2
3
>> MyList = ['apple', 'apple', 'banana', 'banana', 'pear']
>> {idx: value for (idx,value) in enumerate(set(MyList))}
{0: 'banana', 1: 'pear', 2: 'apple'}

例示字典的三种Python解决方案的摘要。有一个"一线"解决方案永远不应该是最重要的考虑。

1。预先定义的键和默认值。

使用dict.fromkeys而不是为每个键设置默认值。另外,不要将变量命名为与类相同的名称,例如使用lst

1
dic2 = dict.fromkeys(lst, 0)

2。预先定义的默认值,但不是键。

或者,如果将来要添加更多的密钥,可以考虑使用collections.defaultdict,它是dict的一个子类:

1
2
3
from collections import defaultdict
dic2 = defaultdict(int)
dic2['newkey']  # returns 0 even not explicitly set

三。与函数相关的键和值。

对于通过函数链接键和值的字典的构建,使用字典理解,如@omerb所详细描述的,例如。

1
2
{k: f(k) for k in lst}  # value function of given keys
{f(v): v for v in lst}  # key function of given values


使用dict构造函数、mapzip的case-01简单的一行语句:

1
2
3
>>> l = ['a','b','c']
>>> dict(zip(map(hash,l),l))
>>> {12416037344: 'a', 12672038114: 'c', 12544037731: 'b'}

第二种情况:

1
2
3
4
>>> l = ['a','b','c']
>>> default_value = 10
>>> dict((zip(l,[default_value]*len(l))))
>>> {'a': 10, 'c': 10, 'b': 10}

这两个结构可以使用字典理解构建,例如:

代码:

1
2
dic_comp = {getattr(elt, 'hash'): elt for elt in test_data}
dic2_comp = {elt: defaultValue for elt in test_data}

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class TestObj(object):
    def __init__(self, hash_value):
        self.hash = hash_value

test_data = [TestObj(i) for i in range(5)]

dic = {}
for elt in test_data:
    dic[elt.hash] = elt

dic_comp = {getattr(elt, 'hash'): elt for elt in test_data}
assert dic == dic_comp

dic2 = {}
defaultValue = 0
for elt in test_data:
    dic2[elt] = defaultValue

dic2_comp = {elt: defaultValue for elt in test_data}
assert dic2 == dic2_comp