Live data from Hacker News

Anti-Patterns in Python Programming

lignos.org

41–50 of 242 posts

Re: Anti-Patterns in Python Programming

#41
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)

you can consider a list comprehension to be a sort of literal representation of the result of map. I think literals have a benefit for code readability and should be used when feasible (i.e. the literal is compact enough).

the other reason its considered more idiomatic in Python is just because the compiler does a better job of parsing and optimizing list comprehensions.

Re: Anti-Patterns in Python Programming

#42
post #34
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!

Couldn't agree more! One of my all time new python interview questions gets a surprisingly large number of developers. Given a function like: def append_one(l=[]): l.append(1) return l What does this return each time? >>> append_one() >>> append_one() >>> append_one()

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 how default parameters work), but without the confounding problem of similar-looking characters. Of course, syntax highlighting would help the applicant out.

All of that being said, I still don't doubt that many developers don't know what they should about default parameters.

Re: Anti-Patterns in Python Programming

#43
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)

I think the main reason is the lambda syntax. List comprehensions also let you do filter and nested loops.

Re: Anti-Patterns in Python Programming

#44

Earlier quoted context omitted.

I do that all the time in the interpreter, especially when slicing pandas DataFrame objects, e.g.: df_subset = df['date buyer nwidgets'.split()] That is far easier to type than the explicit list, with all its punctuation. Now, it's definitely weird that they did a `split(" ")` rather than just using the default, but the idea is the same. I do try to strip stuff like that out before I put it into a script, replacing i…

I don't mean to be pedantic, but a list (I am assuming df is a list) requires an int. (That sentence I wrote about using hashable types need not apply, sorry!) If you ran that code, you would get this error: TypeError: list indices must be integers, not list

That's a pandas dataframe (idiomatically denoted df), not a list. It has funky slicing properties, and he's selecting columns of the dataframe in a perfectly valid way.

Re: Anti-Patterns in Python Programming

#45
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?

Map and filter, of course; less syntactical noise, simple function semantics, and plenty of precedent and equivalents in all other languages.

Re: Anti-Patterns in Python Programming

#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, mylist)

Plus python also has set comprehension and dict comprehension, which share essentially the same syntax.

Re: Anti-Patterns in Python Programming

#47
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?

Those are not equivalent. You need to wrap the map in a list() call.

Re: Anti-Patterns in Python Programming

#48

Earlier quoted context omitted.

> Mutables as default function/method arguments It would really make sense to change the semantics of Python to fix this issue.

Change them how, to no longer have functions be first class objects? The behavior of mutable default arguments is clear if you know how Python treats function objects. Any "fix" would handicap the language.

Can you clarify?

    def foo(default_arg = []):
Why can't that just be shorthand for:

    def foo(default_arg = ParamNone):
        if default_arg == ParamNone:
            default_arg = []
How would that break first class functions?

Re: Anti-Patterns in Python Programming

#50
post #34

Earlier quoted context omitted.

Couldn't agree more! One of my all time new python interview questions gets a surprisingly large number of developers. Given a function like: def append_one(l=[]): l.append(1) return l What does this return each time? >>> append_one() >>> append_one() >>> append_one()

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?
Post reply on HN