Speaking of find\_item, is the `for..else` loop (which can be used to write find\_item in another way) considered Pythonic? I personally like `for..else` loops but I don't know where the consensus is at.
http://en.wikipedia.org/wiki/No_true_Scotsman Don't ask what's "more Pythonic" or "less Pythonic", Python is not a cult, it's a very practical scripting language. Ask for benefits and weaknesses of a given approach in given circumstances.
Anti-Patterns in Python Programming
181–190 of 242 posts
Re: Anti-Patterns in Python Programming
#182Earlier quoted context omitted.
Everybody, listen to this person!
Then it turns into this: x = [] for word in words: for letter in word: x.append(letter) Which in addition to being far more verbose and less readable, is also less efficient.
x = []
for word in words:
x.extend(word)
from itertools import chain
x = [letter for letter in chain(*words)]
x = list(chain(*words))Re: Anti-Patterns in Python Programming
#183Earlier quoted context omitted.
As a minor point, use "default_arg is ParamNone", since "==" probably won't do the right thing. What breaks is something like: def foo(default_arg = slow_f()): pass Under the shorthand gets turned into: ParamNone = object() def foo(default_arg = ParamNone): if default_arg is ParamNone: default_arg = slow_f() pass This is fine, since everyone would know that the shorthand means to not put slow code there. Instead, peo…
In Python 3 there's the nonlocal keyword to deal with the scoping thing. The default arguments thing is worse than a lot of the stuff Python 3 corrected.
More specifically, given a better 'default arguments thing', how would you interpret:
x = [2]
def f(x=x*5):
x.append(4)
With the earlier conversion it's: x = [2]
def f(x=DefaultArg):
if x is DefaultArg:
x = x*5
x.append(4)
This isn't going to work because the x inside of f() is different than the outside x, and you'll get the error message I mentioned.If you add a nonlocal, as in:
x = [2]
def f(x=DefaultArg):
nonlocal x
if x is DefaultArg:
x = x*5
x.append(4)
then you'll get "SyntaxError: name 'x' is parameter and nonlocal".What other solution are you thinking of?
Re: Anti-Patterns in Python Programming
#184Earlier quoted context omitted.
Why even use a list here? Tuples are for immutable/constant data. a_tuple_of_words = ("my", "tuple", "of", "words") or a_tuple_of_words = "my", "tuple", "of", "words"
...because it's a list? Tuples were supposed to have a structure (at least that's what all the rest of the world thinks of them), so iterating through combination of apples, cars and languages makes no sense whatsoever. But yes, Python misses entirely the point of tuples, treating them as read-only lists. http://dozzie.jogger.pl/2014/04/11/python-tuples-the-useless...
No, a structure is, you know, a structure -- what C calls a struct. Python calls it a namedtuple. If some people call it just a tuple, well, that's a difference in terminology, but it doesn't mean Python is confused about the concepts, it's just using terminology you're not used to.
Also, if we're going to be pedantic about the meaning of data types, your blog post is wrong about lists. You say "position in the list doesn't matter", but that means ordering doesn't matter, and an unordered collection of similar objects is a set, not a list. Python makes this distinction clear: a list is ordered, a set is not.
Re: Anti-Patterns in Python Programming
#185Earlier quoted context omitted.
> The default value gets created when the function is interpreted ("compiled"). No. The default value gets "created" (the expression is evaluated and stored) when the def statement is executed. Take the following example: In [1]: def foo(): ...: def append_five(l=[]): ...: l.append(5) ...: return l ...: return append_five ...: In [2]: a = foo() In [3]: b = foo() In [4]: a() Out[4]: [5] In [5]: b() Out[5]: [5] In [6]:…
I thought that was what he meant. Is there any sharp distinction between "interpreting" and "evaluating" in python that I am unaware of? I've always used the words more or less interchangeably. But now that I think about it that might be a little naive since I have no idea how it works under the hood
Re: Anti-Patterns in Python Programming
#186Earlier 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()
At what level would you test an interviewee with this kind of question: Python guru, Python expert, Python ninja, Python rockstar, or merely "is familiar with Python"? Your example is a very common gotcha that has been covered ad nauseam, but IMO it's still the kind of bug that would be caught immediately in code review and is very easily fixed.
Re: Anti-Patterns in Python Programming
#187Earlier quoted context omitted.
Then it turns into this: x = [] for word in words: for letter in word: x.append(letter) Which in addition to being far more verbose and less readable, is also less efficient.
For loops can often be avoided. I would write this particular example in one of these ways, that I think are readable: x = [] for word in words: x.extend(word) from itertools import chain x = [letter for letter in chain(*words)] x = list(chain(*words))
Re: Anti-Patterns in Python Programming
#188Why a function named `main`? We're not writing C here, there's no need for a function named `main`. Let's call it something that's actually useful, like `parse_cmd_arguments`
Re: Anti-Patterns in Python Programming
#189Re: Anti-Patterns in Python Programming
#190Failing to use join is a big one. I have seen countless instances of people writing the logic to output commas in between items (like for CSV export) that they want to concatenate into a string. header_line = ','.join( header for header in headers ) csv_line = ','.join( str(dataset[key]) for key in dataset.keys() ) Example for a case of a dictionary mapping a string to a bunch of numbers.
Any reason not to do the first one more compactly? ','.join(headers)