nathancahill
nathancahill

Reputation: 10850

Python algorithm for lists and sublists

I have a number of lists that can be "opened" or "closed", something like this:

lista = ["a", "b", "c"]
listb = ["d", "e"]
listc = ["a", "b", "e"]
listd = ["c", "d"]

I have a master list of all open items:

all_open = ["a", "b", "c", "e"]

and a list of open lists:

open_lists = ["lista", "listc"]

As the sublists are openend, their items are added to the master list:

open_lists.append("listb")
for each i in listb:
    if !(i in all_open):
        all_open.append(i)

Is there a simple algorithm to remove items from the master list when a sublist is closed? The goal is to not remove items that belong to other lists that are still open.

Upvotes: 0

Views: 235

Answers (2)

Keith Randall
Keith Randall

Reputation: 23265

You have to keep track of how many lists each item was from. The simplest way to do that is with a map. I like to use collections.Counter for something like this.

import collections
count = collections.Counter()

# add a list
for i in listb:
    if count[i] == 0:
        all_open.append(i)
    count[i] += 1

# delete a list
for i in listb:
    count[i] -= 1
    if count[i] == 0:
        all_open.remove(i)

In addition, you can get rid of all_open altogether and use the count.keys() iterator instead.

Upvotes: 2

Mateusz Kowalczyk
Mateusz Kowalczyk

Reputation: 2066

Something like

all_items = []
for l in open_lists:
    for item in l:
       if item not in all_items:
           all_items.append(item)

all_open = [item for item in all_open if item not in all_items]

I believe this will results in what you desire although I'm not too clear if that's what you are asking for. You could also keep track of how many times each item is open, and when you close a list, decrease that by 1. If the value is 0, then remove an item. Might be a lot more efficient than this.

Upvotes: 0

Related Questions