用于循环和操作的Python

用于循环和操作的Python,python,Python,嘿,伙计们,我正在查看stackoverflow上另一篇文章中的代码,我注意到了一些关于“for循环”的东西。如果使用“pop”或“remove”更改列表,则会弄乱该内部循环的索引。如果从列表中弹出/删除项目,它将跳过整个项目。我绕过它的方法是,在我操作另一个列表的同时,实际制作一份列表副本,用于“for循环”。我是python新手 我在他的名单上加了一个。我的程序删除任何体重超过180或任何名为乔的人。起初,当我注意到这个问题时,我只是使用了d_列表。然后我就写了“临时名单=临时名单”,我想这

嘿,伙计们,我正在查看stackoverflow上另一篇文章中的代码,我注意到了一些关于“for循环”的东西。如果使用“pop”或“remove”更改列表,则会弄乱该内部循环的索引。如果从列表中弹出/删除项目,它将跳过整个项目。我绕过它的方法是,在我操作另一个列表的同时,实际制作一份列表副本,用于“for循环”。我是python新手

我在他的名单上加了一个。我的程序删除任何体重超过180或任何名为乔的人。起初,当我注意到这个问题时,我只是使用了d_列表。然后我就写了“临时名单=临时名单”,我想这是一个单独的副本,但我想不是。然后我使用list的copy属性使其工作。这样我就不会操纵“for循环”使用的列表

我的问题是,这是正常的吗?我做得对吗?对我来说,如果数据很大,你就不会想复制数据。我提出的另一种选择是使用while循环而不是outer for循环

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