1

I am new to python and linux and to programming in general, sorry for noob questions.

I have a list of cifs shares as below,

['Type', 'Sharename', 'Comment']

[['Disk', '3tb', ''], ['Disk', 'c$', 'Default share']]

I would like to remove all the shares which have a comment same as in the list below,

['Remote Admin', 'Default share', 'Remote IPC']

I wrote the below piece of code that works pretty well but I have to keep calling list = list.copy(). It seems I am missing something here. Is this the right way to do this or is there a better way for the same and it eludes me ?



for skip in self.skip_shares_disc:
    # print("Skip: " + skip)
    for share in all_shares:
        all_shares = all_shares.copy()
        # print("    share[2]: " + share[2] + "drive: " + share[1])
        if str(share[2]).upper() == str(skip).upper():
            all_shares = all_shares.copy()
            # print("        share[2]: " + share[2] + "drive: " + share[1])
            all_shares.remove(share)
            all_shares = all_shares.copy()
Chris Charles
  • 4,406
  • 17
  • 31
vivek dave
  • 13
  • 3
  • 1
    You must make the copy before the `for` loop, and iterate on the copy. In the `for` loop you must remove elements from the original list. – Frodon Jul 19 '16 at 15:28
  • In general, you shouldn't modify something that you're currently iterating over. Instead, iterate through the list, building a list of identifiers you want to remove, then iterate over *that* list, removing items from the `all_shares` list. – jedwards Jul 19 '16 at 15:29
  • Possible duplicate of [Remove items from a list while iterating in Python](http://stackoverflow.com/questions/1207406/remove-items-from-a-list-while-iterating-in-python) – Łukasz Rogalski Jul 19 '16 at 15:38

3 Answers3

2

You are continuously doing all_shares.copy() because you are modifying the list while iterating over it. This patch prevents the for loop from changing with the list mutation; which is usually not desirable.

However, you can drop all the copy by iterating over a slice/copy of the list:

for share in all_shares[:]

This only makes a copy of the list once, as opposed to making two copies on each iteration.

Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139
0

Python uses, in part, concepts from functional programming. If you build a list of things you want to keep and return that to the context you wish to use it in you wont have to delete anything and you wont have to call list.copy() a bunch of times.

hiEntropy
  • 15
  • 1
  • 3
0

There are a couple ways to do this. The most Pythonic is to use a list comprehension...

special_comments = ['Remote Admin', 'Default share', 'Remote IPC']
filtered_shares = [x for x in all_shares if x not in special_comments]

This builds a new list keeping only the items from the original list that you want to keep. This is an example of a filter- which you could actually do using the filter keyword...

special_comments = ['Remote Admin', 'Default share', 'Remote IPC']
def condition(x):
    return x not in special_comments

filtered_shares = filter(condition, all_shares)

In this case, you pass in the original list you want to filter, and a function that will return true/false for each element of the list (True to keep it, False to remove it). You can do it in one line using a Lambda statement...

filtered_shares = filter(lambda x: x not in special_comments, all_shares)

where the lambda defines the function with the def func_name(args) format.

Paul Becotte
  • 9,767
  • 3
  • 34
  • 42