Python scope oddity 🐍❗
N = [1, 2, 3]
def set_N(*nums):
print(N)
N = nums
>>> set_nums([4, 5, 6])
UnboundLocalError: local variable 'N' referenced before assignment
Names can't be both local and global in the same scope. 😮 #pythonoddity
Extending a list in #Python
>>> a = []
>>> a.extend([2, 1]) # neat
>>> a += [3, 4] # hmm ok
>>> a += (7, 11) # huh?
>>> a[-1:] += [18, 29] # uh oh
>>> a[:] = [*a, 47, 76] # 😦
>>> a
[2, 1, 3, 4, 7, 11, 18, 29, 47, 76]
Absurd Python quiz time 🐍🧩⏲️
Guess what this prints. Then try it out from a #Python REPL.
def add_sum(nums=[2, 1]):
nums.append(nums[-1] + nums[-2])
return nums
print(add_sum() or add_sum(), add_sum() and add_sum())
print(*add_sum(), *add_sum())
I tend to avoid #Python's number-related string methods #pythonoddity
def check(s): return s.isnumeric(), s.isdigit(), s.isdecimal()
>>> check("Ⅴ")
(True, False, False)
>>> check("❺")
(True, True, False)
>>> check("𝟝")
(True, True, True)
>>> check("-5")
(False, False, False)
@pauldambra @mrjackdaw
Default values are similar (they apply only when no arg is given):
def f(a="hi"): print(a)
A falsey value counts as a value:
>>> f(None)
None
truthiness is about emptiness, but not missing-ness.
So dict.get method is less like this in JS:
a["item"] || "default"
And more like this in JS:
"item" in a ? a["item"] : "default"
btw another "shallow" operation that's a #pythonoddity for new many is containment.
>>> x = ["hi"]
>>> "h" in x[0]
True
>>> "h" in x
False
If you enjoy #Python Oddities but prefer mediums that aren't Twitter, the best I currently have is this talk: https://trey.io/oddities
I've considered compiling these into a blog post eventually but haven't done so yet. 🤷
Today for #projects: another hashtag I coined, the #pythonoddity hashtag.
Years ago I decided I was going to try tweeting one "python oddity" every week (anything that might be a gotcha for a new Python user). I decided to make a hashtag for it: #pythonoddity.
I still collect #python oddities but I don't share them as regularly as I used to. Maybe I should start that hashtag up again here?
Here's a collection of some of my favorite #pythonoddity tweets over the years: https://twitter.com/i/events/871564334832304128?t=E4efyEDQ58IlJwqJ6MZXYg&s=09
#projects #pythonoddity #python
A Python Morsels user noted that breakpoint() didn't work on their machine:
C:\http://pdb.py:3: RuntimeWarning: Ignoring unimportable $PYTHONBREAKPOINT: "pdb.set_trace"
It took me a more than a moment to spot it. Do you see what caused their issue?
@peterdrake @chris @s_gruppetta
My #PyConUS2022 talk was on #Python oddities and had this #pythonoddity as the punchline
#PyConUS2022 #python #pythonoddity
Still one of the oddest #Python oddities I've ever seen 🐍🤔
>>> a = ([],)
>>> a[0] += ["what"]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> a
(['what'],)
Note that an exception was raised but the operation also worked! 😳 #pythonoddity
Walrus operator / self documenting f-string #pythonoddity
RT @nedbat@twitter.com
Sometimes compact syntax collides in surprising ways. Don't try to be too tricky!
More explanation: https://github.com/python/cpython/issues/97599#issuecomment-1259569502
The string format method in #Python doesn't care whether the string you call it on has all (or even ANY) of the replacement indexes/names you pass it.
>>> template = "Hi {0}. That's all."
>>> template.format("Trey", "Python", version=3.10)
"Hi Trey. That's all."
A Python student found a #pythonoddity that had us both squinting last week.
They couldn't figure out why their output always had "0" & "1" for every input 🤔
The problem: they started with an f-string but also ended up using the string format method 😮
In Python 3.7 and below clearing your globals like that would clear __import__ and would really mess up the Python interpreters state.
That #pythonoddity was resolved in Python 3.8.
Now it can actually be a handy thing to do sometimes. https://twitter.com/2326251343/status/702172824086007809
One of my favorite things about teaching: when my students show me something I'd never thought to try and it doesn't work the way EITHER of us expected it would. I LOVE moments like this. 💖
A walrus operator #pythonoddity that's actually an interesting f-string oddity 👇
Dictionary #pythonoddity
Think about it for a minute.
Then try it yourself 👉 https://pym.dev/r/2asv9/
RT @georgesdubus@twitter.com
Python quizz!
>>> d = {}
>>> d.update([{'name': 'me', 'age': 0}])
Can you guess the value of `d`?
Then can you guess how long that made me lose today?
🐦🔗: https://twitter.com/georgesdubus/status/1555571395714744321
Two thoughts:
1. Breaking things is a fun way to learn #pythonoddity
2. I've considered doing this with regular expressions and match/case (for added confusion since "match" sounds regex-related already) and this really makes me want to finally follow through on that idea. 😬
A subtle error message #pythonoddity
Most objects used with "in" are iterables. But iterables aren't the *only* objects that work with "in".
Should the error message change? 🤔
RT @mariatta@twitter.com
And when you remove the __contains__() then you get an error, saying 'Blabla' is not iterable.
But... I only want the __contain__ but not the __next__ and __iter__.
f-string #pythonoddity
RT @SerhiyStorchaka@twitter.com
@raymondh@twitter.com Be aware that you can get an unexpected result if you do not control your input:
>>> s = 'hello'
>>> n = 10.4
>>> f'{s:^{n}}'
' hell '
🐦🔗: https://twitter.com/SerhiyStorchaka/status/1547238173046149120
A tuple unpacking #pythonoddity 🤔
The moral? Don't use variables as indexes while assigning to them in the same assignment expression. 😜
RT @RealBenjizo@twitter.com
Python question;
What is the output of the following code and why?
>>a = [6,7,8]
>>b = 1
>>b, a[b] = 2, 5
>>print(a)
#100DaysOfCode #DataScience #TensorFlow
@mohib1st@twitter.com
🐦🔗: https://twitter.com/RealBenjizo/status/1547231593919545351
#pythonoddity #100daysofcode #datascience #tensorflow