Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.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字典中不同的迭代有什么区别?_Python_Python 2.7_Optimization_Iteration_Time Complexity - Fatal编程技术网

python字典中不同的迭代有什么区别?

python字典中不同的迭代有什么区别?,python,python-2.7,optimization,iteration,time-complexity,Python,Python 2.7,Optimization,Iteration,Time Complexity,我有一本下面这样的字典 G = {0: {1: 1, 4: 1}, 1: {0: 1, 2: 1}, 2: {1: 1, 3: 1}, 3: {2: 1, 4: 1}, 4: {0: 1, 3: 1}} 我可以通过两种方式迭代这些键: for key in G: do stuff 而且也喜欢 for key in G.keys(): do stuff 哪一种方法更好&蟒蛇法? 另外,哪一种时间复杂度更好?对于输入G是最有效的方法,这两种方法都是O(N),但是对于输入G来说避

我有一本下面这样的字典

G = {0: {1: 1, 4: 1}, 1: {0: 1, 2: 1}, 2: {1: 1, 3: 1}, 3: {2: 1, 4: 1}, 4: {0: 1, 3: 1}}
我可以通过两种方式迭代这些键:

for key in G:
    do stuff
而且也喜欢

for key in G.keys():
    do stuff
哪一种方法更好&蟒蛇法?
另外,哪一种时间复杂度更好?

对于输入G
是最有效的方法,这两种方法都是
O(N)
,但是对于输入G来说
避免了像使用
G.keys()
和额外的函数调用那样不必要地构建列表

In [3]: G = {0: {1: 1, 4: 1}, 1: {0: 1, 2: 1}, 2: {1: 1, 3: 1}, 3: {2: 1, 4: 1}, 4: {0: 1, 3: 1}}

In [4]: %%timeit 
   ...: for k in G:
   ...:    pass
   ...: 
10000000 loops, best of 3: 171 ns per loop

In [5]: %%timeit
   ...: for k in G.keys():
   ...:     pass
   ...: 
1000000 loops, best of 3: 235 ns per loop

这两个键的顺序大致相同,但在第二秒内,您必须为提取
支付一点时间

为了更好地理解,请查看这两种方法的运行时:

def test1():    
   G = {0: {1: 1, 4: 1}, 1: {0: 1, 2: 1}, 2: {1: 1, 3: 1}, 3: {2: 1, 4: 1}, 4: {0: 1, 3: 1}}
   for key in G:
    key+=1

def test2():    
   G = {0: {1: 1, 4: 1}, 1: {0: 1, 2: 1}, 2: {1: 1, 3: 1}, 3: {2: 1, 4: 1}, 4: {0: 1, 3: 1}}
   for key in G.keys():
    key+=1


if __name__ == '__main__':
    import timeit
    print 'test 1 : ',timeit.timeit("test1()", setup="from __main__ import test1")
    print 'test 2 : ',timeit.timeit("test2()", setup="from __main__ import test2")
结果:

test 1 :  0.934647083282
test 2 :  1.02073597908

最常见的是
输入G:
,具有上述所有优点

如果您在循环中操作字典,则G.keys()中的键的
非常有用,而更高效的第一个变量禁止使用字典。对于字典的操作,我的意思是显式地更改字典键(添加/删除项)!这样做将导致
“运行时错误:在迭代过程中更改了字典大小”
。但是您也可以在第一个变体中更改键的关联值,因为它不会更改字典(-length),而是更改键的关联值

所以没有真正的“更好”,只有两个用例!通常,您会使用第一个变体,但如果您想迭代字典并对其进行操作,您会使用第二个变体

编辑
正如Bakuriu在python3中指出的,您必须手动将
G.keys()
转换为列表。我的示例是针对标记的版本2.7的。

仅适用于Python 2.x-在Python 3.x中,
keys()
返回一个迭代器。@isedev问题标记为2.7,而在Python 3中,您仍在使用一个不必要的函数call@isedev:这仍然是一个额外的方法调用,以及一个新对象(dict视图)的创建。但是,它不是O(1)。它仍然是O(N),但固定成本较低。@MartijnPieters,是的,读错了这个问题,他认为如果
如果k in d
Python本身的启动和拆卸时间太长,无法正确显示差异。使用
timeit
模块来显示性能差异。是的,当然,使用
time
命令是我的习惯!我会编辑答案!练习:您可以通过
key in some dict
key in some dict.keys()
检查某个键是否在字典中。1) 它们在渐近复杂性上等价吗?2) 比较python2和python3中(1)的答案。在对集合进行迭代时,不能修改集合!下一个项目是什么?使用dict.keys()可以迭代一系列键,并可以添加或删除字典中的元素。警告:迭代
keys()
并修改字典仅在python2中有效。python3中的
keys()
是一个视图,因此必须手动将其转换为
列表才能正常工作@PadraicCunningham尝试类似这样的操作:
对于i,输入enumerate(some dict):如果i%2==0:del some dict[key]
。这里的“修改”是指字典通过添加或删除元素来改变其大小。重新映射同一个键不是问题。@PadraicCunningham:如果您添加或删除键,您将得到“RuntimeError:迭代期间更改了字典大小”。@PadraicCunningham:您想要什么?也许我不够明确,但你唯一可以改变的是价值观。您不能更改键(的值),因为这意味着添加一个新项,这将更改大小!我现在明确指出这一点是为了避免感觉到模棱两可。