如何在python中有效地删除循环中的列表元素

时间:2018-01-14 11:36:25

标签: python

我的代码如下。

for item in my_list:
        print(item[0])
        temp = []
        current_index = my_list.index(item)
        garbage_list = creategarbageterms(item[0])

        for ele in my_list:
            if my_list.index(ele) != current_index:
                for garbage_word in garbage_list:
                    if garbage_word in ele:
                        print("concepts: ", item, ele)
                        temp.append(ele)
        print(temp)

现在,我希望elemylist附加temp后删除mylist(因此,它不会在主循环中得到处理,因为它是垃圾字。)

我知道当它处于循环中时,从列表中直接删除元素是不好的。因此,我有兴趣知道是否有任何有效的方法可以做到这一点?

例如,如果 mylist = [["tim_tam", 879.3000000000001], ["yummy_tim_tam", 315.0], ["pudding", 298.2], ["chocolate_pudding", 218.4], ["biscuits", 178.20000000000002], ["berry_tim_tam", 171.9], ["tiramusu", 158.4], ["ice_cream", 141.6], ["vanilla_ice_cream", 122.39999999999999]] 如下;

tim_tam

第一次迭代

对于第一个元素yummy_tim_tam,我得到了诸如berry_tim_tamtemp之类的垃圾字。因此,它们会添加到我的yummy_tim_tam列表中。

现在我要从列表中删除berry_tim_tamtemp(因为它们已经添加到yummy_tim_tam),因此它不会从头开始执行。< / p>

第二次迭代

现在,由于pudding不在列表中,因此会执行pudding。对于chocolate_pudding,我会收到一组不同的垃圾字,例如biscuitstiramutemp。因此,它们会被添加到ice_cream并被删除。

第3次迭代

["tim_tam", 879.3000000000001], ["yummy_tim_tam", 315.0], ["berry_tim_tam", 171.9] , ["pudding", 298.2] ["chocolate_pudding", 218.4], ["biscuits", 178.20000000000002], ["tiramusu", 158.4] ["ice_cream", 141.6], ["vanilla_ice_cream", 122.39999999999999] 将被选中。这个过程将继续。

我的最终目标是获得如下三个单独的列表。

 DB_HOST=localhost
 DB_DATABASE=homestead
 DB_USERNAME=homestead
 DB_PASSWORD=secret

3 个答案:

答案 0 :(得分:3)

此代码可生成您想要的内容:

my_list = [['tim_tam', 879.3], ['yummy_tim_tam', 315.0], ['pudding', 298.2],
           ['chocolate_pudding', 218.4], ['biscuits', 178.2], ['berry_tim_tam', 171.9],
           ['tiramusu', 158.4], ['ice_cream', 141.6], ['vanilla_ice_cream', 122.39]
           ]

creategarbageterms = {'tim_tam' : ['tim_tam','yummy_tim_tam', 'berry_tim_tam'],
                      'pudding': ['pudding', 'chocolate_pudding', 'biscuits', 'tiramusu'],
                      'ice_cream': ['ice_cream', 'vanilla_ice_cream']}

all_data = {}
temp = []
for idx1, item in enumerate(my_list):
    if item[0] in temp: continue
    all_data[idx1] = [item]

    garbage_list = creategarbageterms[item[0]]

    for idx2, ele in enumerate(my_list):
        if idx1 != idx2:
            for garbage_word in garbage_list:
                if garbage_word in ele:
                    temp.append(ele[0])
                    all_data[idx1].append(ele)

for item in all_data.values():
    print('-', item)  

这会产生:

- [['tim_tam', 879.3], ['yummy_tim_tam', 315.0], ['berry_tim_tam', 171.9]]
- [['pudding', 298.2], ['chocolate_pudding', 218.4], ['biscuits', 178.2], ['tiramusu', 158.4]]
- [['ice_cream', 141.6], ['vanilla_ice_cream', 122.39]]  

请注意,为了示例的目的,我创建了一个模拟creategarbageterms函数(作为字典),它生成您在帖子中定义的术语列表。请注意使用defaultdict,它允许无限次迭代,即产生无限数量的最终列表。

答案 1 :(得分:2)

我建议这样做:

mylist = [["tim_tam", 879.3000000000001],   
          ["yummy_tim_tam", 315.0],
          ["pudding", 298.2], 
          ["chocolate_pudding", 218.4], 
          ["biscuits", 178.20000000000002],
          ["berry_tim_tam", 171.9], 
          ["tiramusu", 158.4], 
          ["ice_cream", 141.6], 
          ["vanilla_ice_cream", 122.39999999999999]]

d = set()   # remembers unique keys, first one in wins

for i in mylist:
    shouldAdd = True
    for key in d:
        if i[0].find(key) != -1:    # if this key is part of any key in the set
            shouldAdd = False       # do not add it

    if not d or shouldAdd:          # empty set or unique: add to set
        d.add(i[0]) 

myCleanList = [x for x in mylist if x[0] in d]    # clean list to use only keys in set

print(myCleanList)

输出:

[['tim_tam', 879.3000000000001], 
 ['pudding', 298.2], 
 ['biscuits', 178.20000000000002], 
 ['tiramusu', 158.4], 
 ['ice_cream', 141.6]]

如果列表中的事物顺序不重要,您可以直接使用字典 - 并从字典中创建一个列表。

如果您需要子列表,请创建它们:

similarThings = [ [x for x in mylist if x[0].find(y) != -1] for y in d]

print(similarThings)

输出:

[
    [['tim_tam', 879.3000000000001], ['yummy_tim_tam', 315.0], ['berry_tim_tam', 171.9]], 
    [['tiramusu', 158.4]], 
    [['ice_cream', 141.6], ['vanilla_ice_cream', 122.39999999999999]], 
    [['pudding', 298.2], ['chocolate_pudding', 218.4]], 
    [['biscuits', 178.20000000000002]]
]

正如@joaquin在评论中指出的那样,我错过了将creategarbageterms()tiramusubiscuits分组的pudding函数以使问题100%适合 - 我的回答提倡&#34;不要修改交互中的列表,使用适当的集合或字典过滤它到组。这里的唯一键是不是后面提到的键的一部分的键。

答案 2 :(得分:1)

你想要一个循环遍历列表的外部循环,以及一个可以修改同一个列表的内部循环。

我看到你在评论中得到的建议是根本不在内循环中删除条目,而是检查术语是否已经在temp中。这是可能的,并且可能更容易阅读,但不一定是处理时间的最佳解决方案。

我也看到你收到了Patrick使用词典的答案。对于您的特定用例,这可能是最干净的解决方案,但是没有解决标题中更一般的问题,即在循环中删除列表中的项目时。如果由于某种原因这是非常必要的,我建议如下:

idx = 0
while idx < len(my_list)
    item = my_list[idx]
    print(item[0])
    temp = []
    garbage_list = creategarbageterms(item[0])

    ele_idx = 0
    while ele_idx < len(my_list):
        if ele_idx != idx:
            ele = my_list[ele_idx]
            for garbage_word in garbage_list:
                if garbage_word in ele:
                    print("concepts: ", item, ele)
                    temp.append(ele)
                    del my_list[ele_idx]
        ele_idx += 1
    print(temp)
    idx += 1

这里的关键见解是,通过使用while循环而不是for循环,您可以对程序的控制流程进行更详细的“手动”控制,以及在你的循环中更安全地做'非常规'的事情。我只建议这样做,如果你真的不得不出于任何原因。这个解决方案更接近您提出的字面问题,更接近您原来自己的代码,但可能不是最简单的读取/大多数Pythonic代码。