Live data from Hacker News

Anti-Patterns in Python Programming

lignos.org

121–130 of 242 posts

Re: Anti-Patterns in Python Programming

#121
post #32

Earlier quoted context omitted.

Of, off the top of my head: for word in (set(lyrics_list) & set(words)): print('{} is in the lyrics'.format(word))

Even shorter, nice. How about this one liner, the last bit is looking a bit messy any ideas? print " is in the lyrics \n".join([set(lyrics_list) & set(words)]), "is in the lyrics"

Just because it can be written as a one-liner doesn't mean it should be written as a one-liner :)

Don't ever do this.

    print('\n'.join(['{} is in the lyrics'.format(word)) for word in (set(lyrics_list) & set(words))])

Re: Anti-Patterns in Python Programming

#122
post #32

Earlier quoted context omitted.

Even shorter, nice. How about this one liner, the last bit is looking a bit messy any ideas? print " is in the lyrics \n".join([set(lyrics_list) & set(words)]), "is in the lyrics"

How about >>> lyrics_list = ["her", "name", "is", "rio"] >>> words = ["is", "rio"] >>> print '\n'.join("{} is in the lyrics".format(word) for word in set(lyrics_list) & set(words)) rio is in the lyrics is is in the lyrics

Heh, I just replied with pretty much this exact code to someone else trying to make it a one-liner.

Yes, it's possible. I would never, ever publish code like this, though. It's opaque.

Re: Anti-Patterns in Python Programming

#123
post #35

I always struggle to understand why a list comprehension alist = [foo(word) for word in words] is considered more Pythonic than map alist = map(foo, words)

alist = [foo(word) for word in words if word.startswith('a')] alist = map(foo, filter(lambda word: word.startswith('a'), words)) Which reads better?

I don't use FP practices in Python much, but if I did I'd define the filter outside the map, like so:

    begins_with_a = lambda x: x.startswith('a')
    alist = map(foo, filter(begins_with_a, words))

Re: Anti-Patterns in Python Programming

#124

I use python for datamining, and most of my work is done exploring data in iPython. > First, don't set any values in the outer scope that > aren't IN_ALL_CAPS. Things like parsing arguments are > best delegated to a function named main, so that any > internal variables in that function do not live in the > outer scope. How do I inspect variables in my main function after I get unexpected results? I always have my mai…

If you are using the interpreter directly then that particular bit of advice is hard to follow since you basically live in global all the time. For that reason I would say that this advice applies mainly to .py files.

Agreed.

There's a big difference between "scripting" and "writing software" in terms of best practices.

If you're writing some ETL scripts in an IPython notebook, it would be overkill to encapsulate everything to keep your global scope clean.

Re: Anti-Patterns in Python Programming

#125
post #3

The more frequent and dangerous pitfalls are, in my humble opinion: - Bare except: statements (that catches everything , even Ctrl-C) - Mutables as default function/method arguments - Wildcard imports!

Wildcard imports are OK, if and only if the module is specifically designed with this usage in mind.

Example: nose.tools

Re: Anti-Patterns in Python Programming

#126
post #94
post #72

Earlier quoted context omitted.

> The key is object mutability. A list type is mutable and a tuple type is immutable. I don't think the question has much to do with mutability, it isn't surprising to me nor would I imagine most programmers that a list is mutable, that's very common. The surprising part of this question is that the default value of 'l' continues to exist outside the lexical scope of the function, the expected behavior is that the va…

It has something to do with mutability, because if an object is immutable, the behavior of Python matches what the naive developer expects. It's only mutable objects that break those expectations. Don't even get into unexpected behavior in classes: In [1]: class A(object): ...: l = [] ...: In [2]: a, b = A(), A() In [3]: a.l.append("Something") In [4]: a.l Out[4]: ['Something'] In [5]: b.l Out[5]: ['Something'] In [6…

> if an object is immutable, the behavior of Python matches what the naive developer expects

If the object was immutable then append wouldn't work. That's hardly matching expectations.

Re: Anti-Patterns in Python Programming

#127
post #95

Mmm... you should always use 'if x is not None:' imo. It's very common for libraries to make values evaluate to False, and very easy to get bugs if you just lazily test with 'if x'. Sqlalchemy springs to mind immediately as one of the common ones where using any() and if x: is a reeeeeallly bad idea; there are plenty of others. I'm pretty skpetical about modifying your coding behavior based on what libraries you happ…

Especially taking into account the more bizarre bugs (features?) of python: (bool(datetime.time(0)), bool(datetime.time(1))) == (False, True) I always consider `if x:` a bug, unless x can only be a boolean. Furthermore, it seriously hinders readability and clarity of the code.

I was specifically looking through these comments for your example.

I got bit by this once, and it's certainly... strange (it's also surprising). It's considered "behavior consistent with the rest of Python" [1] (which I can agree with) even if it makes little sense in terms of immediate readability to someone who hasn't previously encountered it. Fortunately, the workaround is easy, and it is documented.

There's at least a couple of spats on the mailing list regarding this feature that are of interest to the curious or at least those who are interested in the history of such behavior.

[1] http://bugs.python.org/issue13936

Re: Anti-Patterns in Python Programming

#128

Earlier quoted context omitted.

The l (lowercase L) and the 1 (one) look really similar. Could that be the cause of some confusion? Of course, the function name helps, but most developers have learned not to trust function names to be an accurate description of what the function does, especially in tricky interview questions. Still, I'd change this to something like: def append_five(l=[]): l.append(5) return l It tests the same thing (knowledge of…

I'm not a Python expert, but iirc from various blog posts the "l" variable does not get reset between function calls which will cause undesired behavior. So calling the function 3 times without argument would produce a list of size 1,2, and 3 with the third call rather than 3 lists of size 1. Can any Python guru's confirm?

The expression presented in the parameter list is only evaluated once, and that is when the method is defined. The confusion is that people assume the expression is evaluated every time the method is called.

Re: Anti-Patterns in Python Programming

#129
post #46
post #35

I always struggle to understand why a list comprehension alist = [foo(word) for word in words] is considered more Pythonic than map alist = map(foo, words)

List comprehensions are more flexible and easier to read in the non-trivial case. Sure in the trivial case you show a map might be considered neater, but just adding a filter is enough to make the list comprehension more readable in my mind. Python's lambda syntax also makes using maps and filters quite ugly. Compare: alist = [x**2 for x in mylist if x%3==0] to alist = map(lambda x: x**2,filter(lambda x: x%3==0, myli…

In Haskell, the latter looks like:

  alist = (map (**2) . filter (\x -> x `mod` 3 == 0)) myList
Or:

  alist = (map (**2) . filter ((== 0) . (`mod` 3))) myList
If alist is a transformation, and not applied to myList, it's cleaner:

  alist = map (**2) . filter ((== 0) . (`mod` 3))
Though Haskell also has list comprehensions, with more "mathy" syntax:

  alist = [x**2 | x 

Re: Anti-Patterns in Python Programming

#130
post #66

Earlier quoted context omitted.

I'm not sure what you're getting at here, or what you are expecting tuples to be like. They can have as much "structure" as you need--they're just a collection. Lighter-weight, immutable collections have a use case. The code in OP appears to be one where it makes sense. I follow the rule where variables are mutable IFF they need to be mutable.

Tuples by pythonists are used as they were mere lists, just immutable. This is clearly displayed by Python's own interface. For the rest of the world, tuples are not immutable lists. They are tuples, i.e. collections of "objects" that could share nothing about their type. Tuples often are not even iterable! (Erlang, Haskell) The fact that tuples in Python can have as much structure as one wants is derived from dynami…

Have you looked at named tuples? They shipped in the python standard library sometime in the last few years (they are at least in 3.3) and are clearly intended for storing structured data.

A typical rule of thumb in Python land is that heterogeneous data probably belongs in a tuple, so practice goes a little further than immutable lists.

I think you could improve your demonstration of the usage in the standard library by examining a random selection of usages to try to find out what is typical. But maybe you already looked at more than you talk about in the article (and I understand that this might not be an interesting use of your time).

Post reply on HN