Question: I'm having trouble to define the `__delitem__` or similar method for the class `Container` in the example below. How can I rectify this? Thx.

```
import numpy as np
import pandas as pd

class XLData(object):
    def __init__(self, name):
        self.name = name
        self.data = pd.DataFrame({self.name: list("ASDF" * 2),
                                  'x': np.random.randint(1, 100, 8) })
    def __repr__(self):
        return repr(self.data.head(2))

class Container(object):
    def __init__(self):
        self.counter = 0
        self.items = []
    def append(self, item):
        self.counter += 1
        self.items = self.items + [item]
    def __delitem__(self, name):
        for c in self.items:
            print("element name:{}, to delete:{}".format(c.name, name))
            if c.name == name:
                pass #!
                #del c
    def __iter__(self):
        for c in self.items:
            yield c

a = XLData('a')
b = XLData('b')
c = XLData('c')

dl = Container()
dl.append(a)
dl.append(b)
dl.append(c)
del dl['b']

for c in dl:
    print(c)
# 'b' is still in ..

```

Answer: 
It is a good idea not to modify the array we are looping over in the loop itself. So just pick the index of the item and delete it outside the loop.

```
class Container(object):
    def __init__(self):
        self.counter = 0
        self.items = {}                # create a dict!
    def append(self, item):
        self.counter += 1
        self.items[item.name] = item   # add items to it, keyed under their names
    def __delitem__(self, name):
        del self.items[name]           # this becomes *really* simple, and efficient
    def __iter__(self):
        for c in self.items.values:    # loop over the dict's values to the items
            yield c #

```
The way you have it implemented, it's going to be slow for operations like `del`. And if you wanted to add other methods that return your objects by name like `__getitem__()`, looking them up by iterating through a list will be slow. You probably want a dictionary to hold your `XLData` objects in inside `Container`. And you won't be needing to keep a count of them since the data objects of Python all have a length property.

```
class Container(object): # Python 3 doesn't require 'object' in class decls.
    def __init__(self):
        self._items = {}

    def add(self, item):
        # self._items.append(item) # Why create a new list each time. 
                                   # Just append. 
        self._items[item.name] = item

    def __len__(self):
        return len(self._items)

    def __getitem__(self, name):
        return self._items[name]

    def __delitem__(self, name):
        del self._items[name]      # Simple.

    def __iter__(self):
        for c in self._items.values():
            yield c

```

With a `dict` you get the benefits of both a list and a dictionary: fast access by name, and iteration over items, etc. The `dict` keeps track of the order in which the keys and items are added. It is possible to have more than one data type holding information on your contained objects if you really needed a separate list to sort and iterate over. You just have to keep the `dict` and `list` in sync.

Come to think of it, you could even sort the dictionary without a list if you wanted your class to support a `sort()` operation, just requires a little creativity.

```
def sort(self, key=None):
    self._items = {k: v for k, v in sorted(self._items.items(), key=key)}

```

I think I'm taking it a bit too far now =)