用于循环和操作的Python
嘿,伙计们,我正在查看stackoverflow上另一篇文章中的代码,我注意到了一些关于“for循环”的东西。如果使用“pop”或“remove”更改列表,则会弄乱该内部循环的索引。如果从列表中弹出/删除项目,它将跳过整个项目。我绕过它的方法是,在我操作另一个列表的同时,实际制作一份列表副本,用于“for循环”。我是python新手 我在他的名单上加了一个。我的程序删除任何体重超过180或任何名为乔的人。起初,当我注意到这个问题时,我只是使用了d_列表。然后我就写了“临时名单=临时名单”,我想这是一个单独的副本,但我想不是。然后我使用list的copy属性使其工作。这样我就不会操纵“for循环”使用的列表 我的问题是,这是正常的吗?我做得对吗?对我来说,如果数据很大,你就不会想复制数据。我提出的另一种选择是使用while循环而不是outer for循环用于循环和操作的Python,python,Python,嘿,伙计们,我正在查看stackoverflow上另一篇文章中的代码,我注意到了一些关于“for循环”的东西。如果使用“pop”或“remove”更改列表,则会弄乱该内部循环的索引。如果从列表中弹出/删除项目,它将跳过整个项目。我绕过它的方法是,在我操作另一个列表的同时,实际制作一份列表副本,用于“for循环”。我是python新手 我在他的名单上加了一个。我的程序删除任何体重超过180或任何名为乔的人。起初,当我注意到这个问题时,我只是使用了d_列表。然后我就写了“临时名单=临时名单”,我想这
d_list = [ {'id':1, 'Name': 'Hannah', 'weight':150}, {'id':2, 'Name':'Andrew', 'weight':200}, {'id':3, 'Name':'Joe', 'weight':180},
{'id':4, 'Name':'Joe', 'weight':180}, {'id':5, 'Name':'Steve', 'weight':200}, {'id':6, 'Name':'Joe', 'weight':180},
{'id':7, 'Name':'George', 'weight':180}]
temp_list = d_list
#temp_list = d_list.copy()
print(d_list)
i = 0
for item in temp_list: # may make a while loop
print(item, "i = ", i, end="[")
for k, v in item.items():
print(end="*")
if (k == "weight") and (v > 180):
d_list.pop(i)
print('^popped^', i, end="") # <-- pop but you need an index
i -= 1
elif (k == "Name") and (v == "Joe"):
d_list.remove(item) # <-- remove just uses item to find and remove
print("^removed^", i, end="")
i -= 1
i += 1
print("]")
print(d_list)
print("i = ", i)
d_list=[{'id':1,'Name':'Hannah','weight':150},{'id':2,'Name':'Andrew','weight':200},{'id':3,'Name':'Joe','weight':180},
{'id':4,'Name':'Joe','weight':180},{'id':5,'Name':'Steve','weight':200},{'id':6,'Name':'Joe','weight':180},
{'id':7,'Name':'George','weight':180}]
临时清单=d清单
#temp_list=d_list.copy()
打印(d_列表)
i=0
对于临时列表中的项目:#可以进行while循环
打印(项目“i=”,i,end=“[”)
对于item.items()中的k,v:
打印(end=“*”)
如果(k=“重量”)和(v>180):
d_list.pop(一)
print(“^popped^',i,end=”“)#temp_list=d_list
创建一个引用,这样两个列表中的任何更改都将反映在这两个列表中,这样肯定不会起作用。temp_list=d_list.copy()
创建一个浅拷贝,它将像temp_list=d_list[:]
但避免任何复制的更好方法是使用反向
并从列表中删除元素:
for item in reversed(d_list):
if item.get("weight", 0) > 180 or item.get("Name") == "Joe":
d_list.remove(item)
i -= 1
如果要弹出,可以从末尾开始,使用相反的范围:
for i in range(len(d_list) -1 , -1, - 1):
item = d_list[i]
if item.get("weight", 0) > 180 or item.get("Name") == "Joe":
i -= 1
第三个选项是使用d_list[:]
来改变原始对象/列表:
d_list[:] = [d for d in d_list if d.get("weight", 0) <= 180 and d.get("Name") != "Joe"]
因此,列表comp是最快的,其次是gen exp。如果您知道键始终存在,则使用d[“weight”]
etc..也会更快由于您发现的问题,最好通过创建一个新的符合条件的元素列表来完成这类工作。此外,扫描所有键和值是愚蠢的;字典是通过查找键来使用的:
newlist = []
for item in d_list:
if item["weight"] <= 180 and item["Name"] != "Joe":
newlist.append(item)
使用while循环而不是reversed for循环怎么样?两种方法都有好处吗?@James,使用reversed不会占用额外的空间,谢谢它也起了作用。这应该是>=180,但这是尼克选择的。LOL@James,我只是在测试你;)谢谢,我会给他们看一看。今天是你学到东西的好日子,没有人受伤!;)不是通常情况下,因为列表上的pop
和remove
通常不会用于有效的解决方案。通常对于简单的事情,您会使用列表理解。对于更复杂的事情,可以使用@alexis answer中的for循环。对于初学者来说,这是违反直觉的,但创建一个全新的列表通常比修改一个更有效以这种方式就位。
In [14]: %%timeit
d_list = [{'id': 1, 'Name': 'Hannah', 'weight': 150}, {'id': 2, 'Name': 'Andrew', 'weight': 200},
{'id': 3, 'Name': 'Joe', 'weight': 180},
{'id': 4, 'Name': 'Joe', 'weight': 180}, {'id': 5, 'Name': 'Steve', 'weight': 200},
{'id': 6, 'Name': 'Joe', 'weight': 180},
{'id': 7, 'Name': 'George', 'weight': 180}]
for item in reversed(d_list):
if item.get("weight", 0) > 180 or item.get("Name") == "Joe":
d_list.remove(item)
....:
100000 loops, best of 3: 4.35 µs per loop
In [15]: %%timeit
d_list = [{'id': 1, 'Name': 'Hannah', 'weight': 150}, {'id': 2, 'Name': 'Andrew', 'weight': 200},
{'id': 3, 'Name': 'Joe', 'weight': 180},
{'id': 4, 'Name': 'Joe', 'weight': 180}, {'id': 5, 'Name': 'Steve', 'weight': 200},
{'id': 6, 'Name': 'Joe', 'weight': 180},
{'id': 7, 'Name': 'George', 'weight': 180}]
for i in range(len(d_list) - 1, -1, - 1): # may make a while loop
item = d_list[i]
if item.get("weight", 0) > 180 or item.get("Name") == "Joe":
d_list.pop(i)
....:
....:
100000 loops, best of 3: 4.48 µs per loop
In [16]: %%timeit
....: d_list = [{'id': 1, 'Name': 'Hannah', 'weight': 150}, {'id': 2, 'Name': 'Andrew', 'weight': 200},
....: {'id': 3, 'Name': 'Joe', 'weight': 180},
....: {'id': 4, 'Name': 'Joe', 'weight': 180}, {'id': 5, 'Name': 'Steve', 'weight': 200},
....: {'id': 6, 'Name': 'Joe', 'weight': 180},
....: {'id': 7, 'Name': 'George', 'weight': 180}]
....: d_list[:] = (d for d in d_list if d.get("weight", 0) <= 180 and d.get("Name") != "Joe")
....:
100000 loops, best of 3: 3.23 µs per loop
In [17]: %%timeit
d_list = [{'id': 1, 'Name': 'Hannah', 'weight': 150}, {'id': 2, 'Name': 'Andrew', 'weight': 200},
{'id': 3, 'Name': 'Joe', 'weight': 180},
{'id': 4, 'Name': 'Joe', 'weight': 180}, {'id': 5, 'Name': 'Steve', 'weight': 200},
{'id': 6, 'Name': 'Joe', 'weight': 180},
{'id': 7, 'Name': 'George', 'weight': 180}]
d_list[:] = [d for d in d_list if d.get("weight", 0) <= 180 and d.get("Name") != "Joe"]
....:
100000 loops, best of 3: 2.98 µs per loop
newlist = []
for item in d_list:
if item["weight"] <= 180 and item["Name"] != "Joe":
newlist.append(item)
del d_list