Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x python3:了解`setdefault`字典方法的用法_Python 3.x_Dictionary - Fatal编程技术网

Python 3.x python3:了解`setdefault`字典方法的用法

Python 3.x python3:了解`setdefault`字典方法的用法,python-3.x,dictionary,Python 3.x,Dictionary,我看到了以下代码片段: # list representing sequence of states states = ['a','b','c','d','a','a','a','b','c','b','b','b'] # matrix of transitions M = {} for i in range(len(states)-1): M.setdefault((states[i], states[i+1]), [0])[0] += 1 因此它遍历列表并计算转换,例如a->b

我看到了以下代码片段:

# list representing sequence of states
states = ['a','b','c','d','a','a','a','b','c','b','b','b']

# matrix of transitions
M = {}

for i in range(len(states)-1):
    M.setdefault((states[i], states[i+1]), [0])[0] += 1
因此它遍历列表并计算转换,例如
a->b
b->c
c->c
等等。我知道
setdefault()
会在键不在字典中时插入默认值。但是我不明白为什么默认值是列表本身,在本例中是[0]。另外,
M.setdefault(…)[0]
意味着我们总是选择列表中的第一个元素并递增它


这种方法的原因可能是什么?

它按照您的理解工作-关于为什么使用列表值而不是直接使用整数-使用“纯”整数和
setdefault(…)
不起作用

原因:设置默认值()返回该键的字典值。如果您返回一个列表,您将获得该列表的引用。如果修改列表,更改将反映在字典中(因为:reference)。如果使用整数,则返回该整数,但修改它不会更改分配给dict中键的值

# list representing sequence of states
states = ['a','b','c','d','a','a','a','b','c','b','b','b']

# matrix of transitions
M = {}

for i in range(len(states)-1):
    M.setdefault((states[i], states[i+1]), [0])[0] += 1

print(M)
输出:

{('a', 'b'): 2, ('b', 'c'): 2, ('c', 'd'): 1, ('d', 'a'): 1, 
 ('a', 'a'): 2, ('c', 'b'): 1, ('b', 'b'): 2}
{('a', 'b'): 2, ('b', 'c'): 2, ('c', 'd'): 1, ('d', 'a'): 1, 
 ('a', 'a'): 2, ('c', 'b'): 1, ('b', 'b'): 2}
如果不想使用包含单个计数器整数的列表,可以执行以下操作:

for i in range(len(states)-1):

    # does not work, error:   M.setdefault((states[i], states[i+1]), 0) += 1 
    M.setdefault((states[i], states[i+1]), 0)  
    M[(states[i], states[i+1])] += 1
print(M)
输出:

{('a', 'b'): 2, ('b', 'c'): 2, ('c', 'd'): 1, ('d', 'a'): 1, 
 ('a', 'a'): 2, ('c', 'b'): 1, ('b', 'b'): 2}
{('a', 'b'): 2, ('b', 'c'): 2, ('c', 'd'): 1, ('d', 'a'): 1, 
 ('a', 'a'): 2, ('c', 'b'): 1, ('b', 'b'): 2}
但这需要两行代码——不能直接赋值给整数

我个人可能会:

# list representing sequence of states
states = ['a','b','c','d','a','a','a','b','c','b','b','b']

# matrix of transitions 
from collections import defaultdict
M = defaultdict(int)

for a, b in zip(states,states[1:]):
    M[(a,b)] += 1 

print(dict(M))  # or use M directly - its str-output is not that nice though

哪一个应该比使用基本字典更有效?这不是合法的Python代码。如果不解释这段代码试图实现什么,你希望有人如何解释这个特定的实现?Patrick,谢谢你的全面回答。返回一个列表会得到对该列表的引用——它是Pyhon列表的一个属性,还是任何迭代对象?另外,为什么
M.setdefault((states[i],states[i+1]),0)+=1
失败?@Mark因为原始事物存储列表。您从dict中检索列表引用的副本,并通过它修改两个引用所指向的数据。您的try将返回一个整数的副本-如果您修改它,您不会修改原始的整数,您只需为它的副本分配一个新值。