Python Shortcuts for the Python Beginner
maxburstein.com
maxburstein.com
if 'key' in d:
val = d['key']
else:
val = d['key'] = 'some default value'
You can do this: val = d.setdefault('key', 'some default value')
This is super-useful for configuration in frameworks, for example - it's a one-liner to set a default config value if the user didn't provide one. logins = {}
for user, date in getLogins():
logins.setdefault(user, []).append(date)
Here you login ends up having one key per "user" with a list of "date". from collections import defaultdict
logins = defaultdict(list)
for user, date in getLogins():
logins[user].append(date)I'd agree if you'd said "not a lot of key/values," as the setup could supersede the subsequent speedups. However, in that case, the difference is negligible, and we should do what is "pythonic."
val = d['key'] = 'some default value'When using the method, the default value argument will always be evaluated, regardless of whether the dictionary key exists. If the expression that produces the default value is an expensive one or has side effects, the programmer might want to use the try/except variant instead.
A few more useful things:
frozenset: immutable set values. these can be hashed, so you can use them as keys in dicts or put them in sets.
poor-man's transpose via zip:
>>> x = [('a', 'b'), ('c', 'd')]
>>> zip(*x)
[('a', 'c'), ('b', 'd')]
slices can be constructed with the "slice" function and passed around as values: >>> f = lambda x, s : x[s]
>>> first3 = slice(3)
>>> last3 = slice(-3, None)
>>> rev = slice(None, None, -1)
>>> f('hello', first3)
'hel'
>>> f('hello', last3)
'llo'
>>> f('hello', rev)
'olleh'Prefer itertools.izip instead of zip to avoid materializing a new list.
Appending the comma operator to the print statement suppresses the newline character and appends a space instead, which is how print 1, "world" works.
The only tip I'd add is using mapping keys in string formatting operations:
>>> d = {'cow': 'moo'}
>>> print 'the cow says %(cow)s' % d
the cow says mooSo, beginners: Please use print() instead of print, to save you some hazzle when using python3 :)
Python3:
>>> print("hello", "world")
hello world
Python2: >>> print("hello", "world")
('hello', 'world') numbers = [1, 2, 3, 4, 5, 6]
even = []
for number in numbers:
if number % 2 == 0:
even.append(number)
is much easier to read and maintain imho then numbers = [1, 2, 3, 4, 5, 6]
even = [number for number in numbers if number % 2 == 0]
Also: for x in range(1,101):print"Fizz"[x%3*4:]+"Buzz"[x%5*4:]or x
is a piece of code I never want someone else to write that I may someday have to maintain. Write it out the long way and make your teams lives easier.That is, the comprehension is equivalent to saying something like "even contains every number from numbers that is even". The loop is like saying "start with even as the empty list; for each number in numbers, append it to even". It's much easier to understand what even is from the first description.
The for-loop version is much less direct and has too many low-level details--why are you appending to the list and using extra state? From the second definition, you can know what even is just by looking at it; for the first one, you have to think about what the code is doing.
This is the fundamental delineation between imperative and declarative code. The former is about how and the latter is about what. In general, specifying the what is much simpler--and therefore easier to write, easier to work with and easier to maintain--than specifying how to get it.
I suspect you find the for-loop version easier not because it's simpler but because that's what you're used to. And while familiarity is certainly an important factor, it's always relative and temporary: every person is familiar with different things, and you get more familiar with different constructs over time.
Rich Hickey's "Simple Made Easy"[1] talk is a great description of this whole idea. He makes the matter far clearer than I have any hope of doing.
I completely agree with this, and the wider fundamental point throughout your post.
However, I’m not a fan of comprehension syntax. It often gets noisy even for trivial cases like this one: the letters “number” appear four times in just a single line here, which as it turns out is just as much accidental complexity as using the explicit loop control variable in the imperative version and you’ve lost the visual cues to what each means that the indentation gives with the loop. For more complicated transformations, I find comprehension syntax also scales poorly.
I suspect (though I’ve no hard data to back it up) that comprehension syntax actually isn’t very readable in many cases, and that this may be why some people prefer the kind of code in the imperative example rather than any innate preference for imperative style per se. Personally, I’d prefer to highlight the data flow but using more explicit transformations instead, such as (in a hypothetical functional programming syntax):
evens = filter {_ % 2 == 0} numbers
Python’s own syntax for this isn’t quite as neat as some functional programming languages, IMHO, but I still prefer it to the comprehension: numbers = [1, 2, 3, 4, 5, 6]
evens = filter(lambda n: n % 2 == 0, numbers) evens = filter(lambda n: n % 2 == 0, numbers)
with evens = [n for n in numbers if n % 2 == 0]
or evens = [n for n in numbers if not n % 2]
Choosing token names is certainly a differentYou might also consider mentioning both dictionary and set comprehensions along with list comprehensions, as they are the exact same concept, yet even a lot of intermediate Python programmers don't know about them!
#define TRUE 0 #define FALSE 1
back in the day.
Too bad there was no source control in the company then, so I could not find out who was responsible for that travesty and "talk calmly" some sense into them.
Worse, though, Windows defines TRUE and FALSE for you somewhere in windef.h - so you would have to be careful about where your code was included..
http://stackoverflow.com/questions/13885234/python-nested-lo...
Print "Fizz" [x%3*4::]
Since range is going from 0 to 101 I have the impression the result won't match the directive."fizz"[0] is the zeroth character in the list / string
Note "fizz"[:] will output all chars in the string (implicitly it's [0:] - from zeroth string to end
X % 3 is x modulo 3, producing 0 only if x is divisible by three - so we want to print fizz here. 4 is the number of chars in both fizz and buzz - so the meat is
"fizz"[x%3*4:] is "fizz"[0:] if x%3 is 0 - when we want tp print fizz, otherwise it's [somevaluegreaterthan4: to the end of the list (ie nothing). The extra : stops index error
The second : might be included to make the slicing more visible.
But what do you get if x is 0 ? As I now uneerstand it, you would get "fizzbuzz". Shouldn't the list start at value 1 ? So shouldn't the range be (1, 101) instead of (101) ?
for x in range(1,101):print"Fizz"[x%34:]+"Buzz"[x%54:]or x
I basically just removed the extra colons and added 1, to the range so that it starts at 1. lifeisstillgood was spot on with the reasoning that this works.
I would also mention `getattr` similarly to `get`.
More things to consider: dict.iteritems, collections.defaultdict, enumerate(seq, 1)
`something` should be written as repr(something). `` (backticks) are gone in Python 3.
if 0 < x > 1: is syntactically correct but it should be written as: if x > 1. The combining syntax could be used for the same direction e.g., if -1 < x < 1.
Code golf is not the strong side of Python and it is not the point of FizzBuzz. Code golf might demonstrate language features but it doesn't provide the correct context for their usage i.e., code golf doesn't show to a beginner how something should be used correctly.
True/False are keywords Python 3 (you can't assign to them).