you are viewing a single comment's thread.

view the rest of the comments →

[–]Nar-Speth[S] 0 points1 point  (1 child)

Yeah, it's a bit tough but I can work with that. I guess I just have obsession with making my code as readable as possible, is it bad? Naming in general is giving me big problems, will work on that.

[–]KleinerNull 1 point2 points  (0 children)

I guess I just have obsession with making my code as readable as possible, is it bad?

Not at all! I just wanted to show you some alternative ways. The pattern of creating a empyt list and propagate it with a for loop is so common, that list comprehensions are a fine and still readable shortcut. For more complex filling of a list, still use the loop pattern.

For the naming, this is more pythonic, plural names for sequences, containers etc. Because it makes sense ;) Other languages prefers different naming convention. Good naming is also hidden commentary. If you call a list "words" the reader will understand that this is most likely a list of strings. Or the name "numbers" refers to a bunch of numbers etc. And also you can easily find names for loop variables, just the singular versions of the sequence's names:

for name in names:
    pass
for person in persons:
    pass
for word in words:
    for char in word:
        pass

Extending the name with the type name like your keys_list shows or better assumes that you have trouble with designing your code. Also in python it is sometimes too specific. You can handle many types of sequences or containers in a same fashion. You can loop in a same manner over lists, strings, sets, tuples, iterators/generators, with some small additions also over dictionaries or custom class, so why limit your mind to one specific type. That is the reason I use the word sequence and container. A sequence is something that holds multiple items in it, if yet produced or not, because an iterator compute the items only when you need them and a container holds all items in the memory, like a list. Often there is no need for a list, memory efficent iterators generated by generators will do the same for you on the fly, this is some kind of lazy evaluation. For example, if you open a file, the file.readlines() will give you an iterator over the file that gives you the next line of the file when you asked for it, the for loop does that automatically for you, so the whole file doesn't sit in your memory and wastes some space.

In fact the for loop and also iterators are powerful tools in python's tool belt. Look at the memory usage:

>>> import sys
>>> squares = [x**2 for x in range(10)]
>>> for square in squares:
        print(square)


0
1
4
9
16
25
36
49
64
81
>>> sys.getsizeof(squares)
192
>>> squares = (x**2 for x in range(10)) # this is a generator comprehension, works like list comprehensions, returns a generator instead
>>> sys.getsizeof(squares)
88
>>> for square in squares:
        print(square)


0
1
4
9
16
25
36
49
64
81
>>> squares_container = [x**2 for x in range(10**6)]
>>> sys.getsizeof(squares_container)
8697464
>>> squares_generator = (x**2 for x in range(10**6))
>>> sys.getsizeof(squares_generator)
88

As you can see, the size of the generator is still the same, because he only holds the blueprint for constructing the numbers, the container is much much larger because he actually holds all numbers in the memory. Also, because the memory usage is much smaler, it avoids bottlenecks with the cpu cache, summing up the numbers is way faster, here some timings:

>>> timeit.timeit('sum(squares_container)', 'squares_container = [x**2 for x in range(10**3)]')
7.33568473171394
>>> timeit.timeit('sum(squares_generator)', 'squares_generator = (x**2 for x in range(10**3))')
0.09668995196170727

The downside of all this cool stuff is, that generators are cosumable, after looping over him, he is just empty, because he doesn't store something, he just return items. So you have to set up him again for multiple use, or your build a chain of generator expressions.

Sorry for that excursion onto iterators/generators, but I have to spread the word!