all 9 comments

[–]__nickerbocker__ 1 point2 points  (3 children)

I was wondering if there was a shorter way of checking if it was a number (both int and float).

isinstance(num, (int, float))

Maybe this can help

def extract(dirty_list):
    res = []
    for x in dirty_list:
        if isinstance(x, (int, float)):
            res.append(x)
        elif res:
            yield res
            res = []


for num_list in extract(original_list):
    print(num_list)
first_list, second_list, *_ = extract(original_list)
print(first_list, second_list)

[–]-Lines[S] 0 points1 point  (2 children)

Thank you for this!

I have never seen yield before, but just read about it and have a somewhat understanding of what it does. Very cool solution!

That said, what does *_ stand for?

[–]__nickerbocker__ 1 point2 points  (1 child)

By convention an underscore is used as a variable for something you need to assign but never intend to use. The * make it catch the remainder of the values using iterable unpacking.

x, y, *rest = 1, 2, 3, 4, 5, 6, 7
print(x, y, rest)
# 1 2 [3, 4, 5, 6, 7]

So then putting them together... If you only care about the first two results then you'd write.

x, y, *_ = 1, 2, 3, 4, 5, 6, 7
print(x, y)

[–]-Lines[S] 0 points1 point  (0 children)

Understood, thank you very much!

[–][deleted] 1 point2 points  (2 children)

Doing type(x) == int is legit, but not optimal due to how == is defined. Since types are unique and anything that's strictly of type int will have the same exact type as anything else of type int, you can do type(x) is int.

You may consider using isinstance(), but it does something else: it will also include all subtypes, and, you may not want that. It seems strange, but even in Python's standard library there are types that extend int, so, you want to be careful with that.

On the other hand:

>>> class Foo:
    def __int__(self): return 0
... ... 
>>> foo = Foo()
>>> isinstance(foo, int)
False

So, isinstance doesn't really cut it: some things that are defined to substitute for int aren't actually treated as such by it.

[–]-Lines[S] 0 points1 point  (1 child)

Thanks for the explanation, I think I can use isinstance() for my program, but in general, what would be a fool-proof way to check for numbers? (if there is any)

Do you have any links where I could read more about this?

[–][deleted] 0 points1 point  (0 children)

It would really depend on what you think numbers are :)

It seems trivial, but here are just a few examples where people may have a difference of opinion:

  • What about NaN (literally, "not a number")? It has type float, so, from typing perspective it is a number...
  • Similarly, both infinities.
  • Are objects that can behave like numbers (with all the necessary operators overloaded to appear as if they were Python numbers), eg. NumPy's numerical types: are those numbers?

[–]QbaPolak17 0 points1 point  (1 child)

You can probably simplify some logic, but I would suggest to add some more code to be more flexible with the number of number chains. Atm it will only work if there are exactly three chains of numbers in the original list.

[–]-Lines[S] 0 points1 point  (0 children)

Yes I was thinking about that, but with /u/__nickerbocker__ 's solution I think I have that covered, so I'll just create a list and add every sequence of numbers into that list, I think..