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:您想要什么?也许我不够明确,但你唯一可以改变的是价值观。您不能更改键(的值),因为这意味着添加一个新项,这将更改大小!我现在明确指出这一点是为了避免感觉到模棱两可。