News for hackers. Stuff that matters.
Re:Python built-ins worth learning (2019) by Buttons840 on Wednesday March 09, 2022 @09:26PM (#30622563)

    # Instead of doing this
    if len(numbers) == 0:
        print("The numbers list is empty")

    # Many of us do this
    if not numbers:
        print("The numbers list is empty")
I tend to write the first form because it is how I think, and I'm writing what I think. "If this list is empty, then..." I suppose a list is only falsy if it is empty. I used to exploit Python's truthyness / falsyness a lot more, but now I like to be more explicit. Ultimately it doesn't matter much, making a single line a tiny bit longer is rarely the most important issue in a project.
Re:Python built-ins worth learning (2019) by adhocmobility on Friday March 11, 2022 @07:38AM (#30639064)
The second case is preferable if numbers is an Optional[List], which is usually the case when passing lists around as arguments.

  def custom_sum(numbers: Optional[List[int]] = None) -> int:
    if not numbers:
      ## something

    return sum(numbers)
This can handle both cases - if numbers is None, or numbers is []
Re:Python built-ins worth learning (2019) by tony-allan on Thursday March 10, 2022 @12:07AM (#30623423)
If you use the technique more generally, you need to watch out for the first case:

  bool(0) -> False
  bool(1) -> True
  bool(str('0')) -> True
  bool(str('')) -> False
  bool(None) -> False
If you are checking that a variable is set bool(some_var) doesn't work for 0.
Re:Python built-ins worth learning (2019) by actually_a_dog on Wednesday March 09, 2022 @09:32PM (#30622581)
Wouldn't it be easier to say

    if numbers == []:
       print ("The numbers list is empty")
if your intent is to express "is the list empty?" in the condition?
Re:Python built-ins worth learning (2019) by sritchie on Wednesday March 09, 2022 @09:43PM (#30622641)
That condition would fail on non-list sequences, like `numbers == (1,2,3)`; the `len` version makes the code more permissive.
Re:Python built-ins worth learning (2019) by mturmon on Wednesday March 09, 2022 @10:12PM (#30622828)
I often use the same if len() construct.

It will fail for non-list inputs, which is another reason it can be handy if you want clarify that you’re enforcing a list.

Re:Python built-ins worth learning (2019) by dec0dedab0de on Wednesday March 09, 2022 @10:50PM (#30623040)
I often use the same if len() construct.

It will fail for non-list inputs, which is another reason it can be handy if you want clarify that you’re enforcing a list.

len will work for strings, tuples, dicts, sets, plus all kinds of custom classes that implement the __len__ magic method.

Re:Python built-ins worth learning (2019) by Buttons840 on Wednesday March 09, 2022 @10:45PM (#30623013)
Ah yes, that's another reason I do it, but I failed to mention. If you see "if not x:" then you're left wondering what x is (a boolean presumably), but "if len(x) == 0:" let's you know you're checking to see if a container is empty.
Re:Python built-ins worth learning (2019) by saila on Wednesday March 09, 2022 @11:55PM (#30623368)
If you want to do type-checking, I don't think this a good way to do it. As a sibling comment points out, it doesn't work all that well since many objects respond to `len()`. I think it would be preferable to add type annotations and use mypy to check them or perhaps, in rare circumstances, do an isinstance check.
Re:Python built-ins worth learning (2019) by mturmon on Thursday March 17, 2022 @01:46PM (#30713908)
Alas, I find this suggestion unpersuasive for the use I have in mind. I get that there would be cases it does apply to.

I just want to enforce that the object acts like a list, mainly versus a float, int, or boolean. Tuples are definitely 100% ok, and if someone wants to give me a set, that's almost certainly OK too, in the use cases I'm considering. And so is a numpy vector!

Often these objects are held in a container (a dict or class variable), so type annotations would be clumsy as far as I know. Wouldn't I need to create a separate object to enforce the annotation?

And the type annotation would need to allow tuples and all flavors of lists or numpy arrays.

On the other end of the scale, I don't think either of us wants to use isinstance checks!

My primary intent isn't to be bulletproof, it's to show intent. The main fail of using len() in this way is that it accepts strings.

Re:Python built-ins worth learning (2019) by saila on Monday March 21, 2022 @09:00PM (#30761687)
I don't see how using len() this way is any different than doing an isinstance check. You're essentially saying, "If this object doesn't respond to len(), raise a TypeError."
Re:Python built-ins worth learning (2019) by dragonwriter on Thursday March 24, 2022 @02:07AM (#30786773)
> I don't see how using len() this way is any different than doing an isinstance check.

It's a protocol (structural) runtime type check, not a class (nominal) runtime type check.

Re:Python built-ins worth learning (2019) by saila on Wednesday March 30, 2022 @12:43AM (#30851555)
Perhaps true but misses the point. If you’re using len() for type checking, it’s essentially no different than doing isinstance(items, Sized). The latter explicitly calls out what you’re doing and makes it clear, to me, that’s it’s not really correct, in that it doesn’t show your intent, which is to enforce a sequence of items in a container not that the object has a size.
Re:Python built-ins worth learning (2019) by mturmon on Thursday March 24, 2022 @01:54AM (#30786729)
Tuple, list, and numpy array are all different isinstance()’s, so I’d have to call them all out. len() avoids that.
Re:Python built-ins worth learning (2019) by saila on Wednesday March 30, 2022 @12:39AM (#30851537)
This is incorrect, because you can generally do this for sequence types:

    isinstance(items, Sequence)
Or perhaps:

    isinstance(items, Iterable)  # works with numpy arrays
Or, equivalent to using len() for type checking, you could do:

    isinstance(items, Sized)
Re:Python built-ins worth learning (2019) by dragonwriter on Thursday March 10, 2022 @12:35AM (#30623554)
“supports len()” and “is a Sequence” are fairly reliably equivalent, and using len() fails fast in many cases (e.g., iteration over a potentially infinite iterable) not doing so would not and be less desirable.

Type checking via mypy, pyright, etc., is great, but in library (as opposed to an app) you can't count on consumers doing that, and isinstance() checks don't support duck-typing.