python 使用 for 循环删除列表中的项目

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2057419/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 23:40:41  来源:igfitidea点击:

Delete item in a list using a for-loop

pythonlistfor-loopcollections

提问by kame

I have an array with subjects and every subject has connected time. I want to compare every subjects in the list. If there are two of the same subjects, I want to add the times of both subjects, and also want to delete the second subject information (subject-name and time).

我有一个包含主题的数组,每个主题都有相关的时间。我想比较列表中的每个主题。如果有两个相同的科目,我想添加两个科目的时间,还想删除第二个科目信息(科目名称和时间)。

But If I delete the item, the list become shorter, and I get an out-of-range-error. I tried to make the list shorter with using subjectlegth-1, but this also don't work.

但是如果我删除该项目,列表会变短,并且会出现超出范围的错误。我试图通过使用 subjectlegth-1 来缩短列表,但这也不起作用。

   ...
   subjectlegth = 8
   for x in range(subjectlength):
        for y in range(subjectlength):
            if subject[x] == subject[y]:
                if x != y:
                    #add
                    time[x] = time[x] + time[y]
                    #delete
                    del time[y]
                    del subject[y]
                    subjectlength = subjectlength - 1

回答by Chris Jester-Young

Iterate backwards, if you can:

如果可以,向后迭代:

for x in range(subjectlength - 1, -1, -1):

and similarly for y.

对于y.

回答by Ignacio Vazquez-Abrams

If the elements of subjectare hashable:

如果 的元素是subject可散列的:

finalinfo = {}

for s, t in zip(subject, time):
  finalinfo[s] = finalinfo.get(s, 0) + t

This will result in a dict with subject: timekey-value pairs.

这将导致一个带有subject: time键值对的字典。

回答by Ned Batchelder

The best practice is to make a new list of the entries to delete, and to delete them after walking the list:

最佳做法是为要删除的条目创建一个新列表,并在遍历列表后删除它们:

to_del = []
subjectlength = 8
for x in range(subjectlength):
    for y in range(x):
        if subject[x] == subject[y]:
            #add
            time[x] = time[x] + time[y]
            to_del.append(y)

to_del.reverse()
for d in to_del:
    del subject[d]
    del time[d]

回答by MAK

An alternate way would be to create the subject and time lists anew, using a dict to sum up the times of recurring subjects (I am assuming subjects are strings i.e. hashable).

另一种方法是重新创建主题和时间列表,使用 dict 来总结重复主题的时间(我假设主题是字符串,即可散列)。

subjects=['math','english','necromancy','philosophy','english','latin','physics','latin']
time=[1,2,3,4,5,6,7,8]
tuples=zip(subjects,time)
my_dict={}
for subject,t in tuples:
    try:
        my_dict[subject]+=t
    except KeyError:
        my_dict[subject]=t
subjects,time=my_dict.keys(), my_dict.values()
print subjects,time

回答by Reza Dodge

Though a whileloop is certainly a better choice for this, if you insist on using a forloop, one can replace the listelements-to-be-deleted with None, or any other distinguishable item, and redefine the listafter the forloop. The following code removes even elements from a list of integers:

虽然一while环无疑是这一个更好的选择,如果你坚持使用一个for回路,可以换list用无,或其他任何区分item元素将要删除的,并重新定义listfor循环。以下代码从整数列表中删除偶数元素:

nums = [1, 1, 5, 2, 10, 4, 4, 9, 3, 9]
for i in range(len(nums)):
  # select the item that satisfies the condition
  if nums[i] % 2 == 0:
    # do_something_with_the(item)
    nums[i] = None  # Not needed anymore, so set it to None
# redefine the list and exclude the None items
nums = [item for item in nums if item is not None]
# num = [1, 1, 5, 9, 3, 9]

In the case of the question in this post:

对于这篇文章中的问题:

...
for i in range(subjectlength - 1):
  for j in range(i+1, subjectlength):
    if subject[i] == subject[j]:
      #add
      time[i] += time[j]
        # set to None instead of delete
        time[j] = None
        subject[j] = None
time = [item for item in time if item is not None]
subject = [item for item in subject if item is not None]