0
class Bag:
    def __init__(self, i=None):
        self.bag = []
        if i == None:
            pass  # i is None, do nothing after create empty bag
        elif type(i)==list:
            self.bag.extend(i) # append whole list i into bag with extend method
        else:
            self.bag.append(i) # append single item i into bag 

    def __repr__(self):
        for s in self.bag :
            return s

    def __str__(self):
        for s in self.bag :
            return s

In the __str__method. It supposed to return a string.

The list is Bag(['a', 'c', 'b', 'b', 'd', 'd', 'd']). And

__str__ is supposed to return Bag(a[1], c[1], b[2], d[3])

Can anyone tell me how to make it work? Many thanks.

jiahuiding
  • 83
  • 7

1 Answers1

1

You can use a collections.Counter here to help:

def __str__(self):
    counts = Counter(self.bag)
    count_str = ','.join('{}[{}]'.format(k, v) for k, v in counts.items())
    return 'Bag({})'.format(count_str)

The great thing about this is that the counter does all the work of figuring out how many of each item are in your bag. All the rest of it is just formatting details. One downside is that the counter is not ordered. If you want an order, you could use the .most_common method (which will order the counts from most common to least-common), or you could use something like an ordered unique recipe to figure out how you want to iterate over the counter.

Community
  • 1
  • 1
mgilson
  • 300,191
  • 65
  • 633
  • 696
  • Using a Counter defeats the purpose of implementing a bag (bag = Counter). He should be using a dictionary to store the item from the beginning. – Adam Van Prooyen Oct 24 '16 at 03:50
  • @AdamVanProoyen -- It's true that `Counter` makes a really nice `Bag` (and it's intended too). It's a bit unclear to me how OP is going to use the above code, but it might just be algorithms practice and he/she wants some quick `str`/`repr` to check while debugging or something ... – mgilson Oct 24 '16 at 05:25