Basically, I personally take issue with the way Python handles global variables and, until Python 3, completely fails to handle non-local variables.
Let's take a trivial example that would work in JavaScript or Scheme. Often, I want to keep track of how many times a particular function gets called (usually for debugging). I would expect to be able to do something like this:
counter = 0
def foo(bar, baz):
counter += 1
...
This does not work in Python. You could use the global keyword to work around this:
This is something of an ugly hack in the language design. Moreover, this falls apart if counter is not in the global scope itself--for example, if foo is defined inside another function. Python 3 introduces the nonlocal keyword to deal with this.
Fundamentally, this problem stems from the fact that Python conflates two fundamentally different operations: defining a variable and mutating it. I personally really like how Scheme handles this: defining and setting are two different actions, and trying to set a variable that has not been defined is an error. This makes the intentions of the programmer much clearer.
A very common pattern in Scheme and JavaScript (as well as other languages I don't use, no doubt) is to use closures to encapsulate state. Thanks to Python's scoping model, this is at best a pain and certainly unnatural.
There are also some minor annoyances. One that gave me problems recently (although it has been fixed in Python 3, I believe), was with list comprehensions:
[i * i for i in range(1, 10)]
print i # gives you 9!
> A very common pattern in Scheme and JavaScript (...) is to use closures to encapsulate state. Thanks to Python's scoping model, this is at best a pain and certainly unnatural.
It is also unnecessary. Python has normal classes, so you can contain your state within objects rather than stackframes.
I don't like either of your examples. Your first example should have been a generator and used a yield rather than a global counter. Your second example is simply bad practice (what do you even expect to happen? It's ambiguous, but i having the value 9 seems to make a reasonable amount of sense).
In my second example, I expect i to not be in the scope. The variable i only makes sense inside the list comprehension and should not be randomly introduced into the outer scope.
For the first example, I don't see how you could replace it with yield, especially if the function foo has to normally return a value when it's used. The core idea is to count how many times foo is called without altering the call site at all. Also, this is an entirely trivial example to illustrate the scoping issue; in practice, there are more complicated reasons to want to set non-local variables, especially from things like helper functions.
The examples don't have to be idiomatic Python to demonstrate Python's weaknesses. In fact, one would expect mature idiomatic forms to skirt language limitations more-or-less by design.
Not a python expert, but python3 has had to add unlocal to let you create a non local variable. Lua requires explicit local, else things are global (which has different problems but seems a more logical choice).
Lua also makes all loop indexes local to the loop which is very clean. Python has difficulty with this.