Python: Cleaner ways to initialize

106 views Asked by At

Or maybe I should say, ways to skip having to initialize at all.

I really hate that every time I want to do a simple count variable, I have to say, "hey python, this variable starts at 0." I want to be able to say count+=1and have it instantly know to start from 0 at the first iteration of the loop. Maybe there's some sort of function I can design to accomodate this? count(1) that adds 1 to a self-created internal count variable that sticks around between iterations of the loop.

I have the same dislike for editing strings/lists into a new string/list.

(Initializing new_string=""/new_list=[] before the loop).

I think list comprehensions may work for some lists.

Does anyone have some pointers for how to solve this problem? I am fairly new, I've only been programming off and on for half a year.

2

There are 2 answers

2
tobias_k On BEST ANSWER

Disclaimer: I do not think that this will make initialization any cleaner. Also, in case you have a typo in some uses of your counter variable, you will not get a NameError but instead it will just silently create and increment a second counter. Remember the Zen of Python:

Explicit is better than implicit.

Having said that, you could create a special class that will automatically add missing attributes and use this class to create and auto-initialize all sorts of counters:

class Counter:

    def __init__(self, default_func=int):
        self.default = default_func

    def __getattr__(self, name):
        if name not in self.__dict__:
            self.__dict__[name] = self.default()
        return self.__dict__[name]

Now you can create a single instance of that class to create an arbitrary number of counters of the same type. Example usage:

>>> c = Counter()
>>> c.foo
0
>>> c.bar += 1
>>> c.bar += 2
>>> c.bar
3
>>> l = Counter(list)
>>> l.blub += [1,2,3]
>>> l.blub
[1, 2, 3]

In fact, this is similar to what collections.defaultdict does, except that you can use dot-notation for accessing the counters, i.e. c.foo instead of c['foo']. Come to think of it, you could even extend defaultdict, making the whole thing much simpler:

class Counter(collections.defaultdict):

    def __getattr__(self, name):
        return self[name]
1
Tristan Vigil On

If you are using a counter in a for loop you can use enumerate:

for counter, list_index in enumerate(list):

the counter is the first variable in the statement and 1 is added to it per iteration of the loop, the next variable is the value of that iteration in the list. I hope this answers your first question as for your second, the following code might help

list_a = ["this", "is"]
list_b = ["a", "test"]
list_a += list_b
print(list_a)
["this", "is", "a", "test"]

The += works for strings as well because they are essentially lists aw well. Hope this helps!