Question

Let's say I want to partition a string. It returns a tuple of 3 items. I do not need the second item.

I have read that _ is used when a variable is to be ignored.

bar = 'asd cds'
start,_,end = bar.partition(' ')

If I understand it correctly, the _ is still filled with the value. I haven't heard of a way to ignore some part of the output.

Wouldn't that save cycles?

A bigger example would be

def foo():
    return list(range(1000))
start,*_,end = foo()
Was it helpful?

Solution

It wouldn't really save any cycles to ignore the return argument, no, except for those which are trivially saved, by noting that there is no point to binding a name to a returned object that isn't used.

Python doesn't do any function inlining or cross-function optimization. It isn't targeting that niche in the slightest. Nor should it, as that would compromise many of the things that python is good at. A lot of core python functionality depends on the simplicity of its design.

Same for your list unpacking example. Its easy to think of syntactic sugar to have python pick the last and first item of the list, given that syntax. But there is no way, staying within the defining constraints of python, to actually not construct the whole list first. Who is to say that the construction of the list does not have relevant side-effects? Python, as a language, will certainly not guarantee you any such thing. As a dynamic language, python does not even have the slightest clue, or tries to concern itself, with the fact that foo might return a list, until the moment that it actually does so.

And will it return a list? What if you rebound the list identifier?

OTHER TIPS

As per the docs, a valid variable name can be of this form

identifier ::=  (letter|"_") (letter | digit | "_")*

It means that, first character of a variable name can be a letter or an underscore and rest of the name can have a letter or a digit or _. So, _ is a valid variable name in Python but that is less commonly used. So people normally use that like a use and throw variable.

And the syntax you have shown is not valid. It should have been

start,*_,end = foo()

Anyway, this kind of unpacking will work only in Python 3.x

In your example, you have used

list(range(1000))

So, the entire list is already constructed. When you return it, you are actually returning a reference to the list, the values are not copied actually. So, there is no specific way to ignore the values as such.

There certainly is a way to extract just a few elements. To wit:

l = foo()
start, end = foo[0], foo[-1]

The question you're asking is, then, "Why doesn't there exist a one-line shorthand for this?" There are two answers to that:

  1. It's not common enough to need shorthand for. The two line solution is adequate for this uncommon scenario.

  2. Features don't need a good reason to not exist. It's not like Guido van Rossum compiled a list of all possible ideas and then struck out yours. If you have an idea for improved syntax you could propose it to the Python community and see if you could get them to implement it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top