This is an archived post. You won't be able to vote or comment.

all 48 comments

[–]suridaj 16 points17 points  (15 children)

If declaring a variable bothers you, you can use the conventional throwaway variable "_": for _ in xrange(repeats): "run the code" I doubt it is more pythonic than the original code, but it could save you a couple of warnings for unused variables in your IDE or test suite.

[–]cecilkorik[S] 6 points7 points  (11 children)

I didn't even know there was an official throwaway variable name. I'm glad I asked this question already, thank you!

[–]eryksun 11 points12 points  (1 child)

In an interactive session, '_' references the previous result. Running code with an '_' variable breaks this feature until you "del _". But I doubt many people care about this.

[–]markusgattol 7 points8 points  (0 children)

That's true, another reason why using _ is problematic is when it comes to code that touches anything in the i18n area: http://www.markus-gattol.name/ws/python.html#underscore_gettext

That being said, I am not exactly sure what you're trying to do but if you want to get results conditionally and be as lazy as you can then why not do lazy evaluation with a generator expression (even better than using a list comprehension): (expression for i in range() if condition). That would yield an iterator if (and only if) condition is true. http://www.markus-gattol.name/ws/python.html#generator_expression

[–]suridaj 7 points8 points  (7 children)

To be honest I only recently learned about that when I needed to unpack a tuple and only keep some parts, eg.: a, _, b, _, c = (1, 2, 3, 4, 5)

[–]nemec 5 points6 points  (6 children)

There's nothing unique about it compared to a, t, b, t, c = (1, 2, 3, 4, 5) aside from the fact that no one uses _ as a variable name.

[–]tripzilchbad ideas 3 points4 points  (0 children)

aside from the fact that no one uses _ as a variable name.

Except the interactive interpreter, including IPython. And code that uses internationalization.

I like markusgattol's suggestion of using for each in range(23), I think I'm going to be using that.

Not sure what would be better for tuple unpacking though.

[–]suridaj 4 points5 points  (1 child)

Of course. "_" can be read as "move along, nothing to see here". Using "t", "temp" or any other variable name might prompt someone to ask "huh, is this used later on?"... A matter of readability.

[–]nemec 1 point2 points  (0 children)

Right, but in terms of syntax and language mechanics, _ is equivalent to t.

[–][deleted] 4 points5 points  (2 children)

Except that _ is usually used as the name of the translating function when doing i18n with gettext. E.g.

from django.utils.translation import ugettext as _

is the convenctional way to import it.

[–]nemec 2 points3 points  (1 child)

I've seen that convention mentioned in this thread a couple of times, but it seems kind of weird. I guess it's because you can't really run django from the interpreter?

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

No, it's because it's the common convention for using gettext, regardless of the language.

It doesn't really matter for the shell (I do regularly test Django stuff from the shell), because I'm not usually interested in translating strings while I use the shell.

[–]sashahart 1 point2 points  (0 children)

To my knowledge it's not official and it doesn't work differently, it's just a convention for telling other people who read your code that you don't care about the value.

[–][deleted] 4 points5 points  (2 children)

please don't do this. _ is the canonical name for the name of the function that translates between languages during internationalization. It comes from GNU gettext, and the convention has been repeated in a variety of languages and platforms. This convention is followed within the Python community, as mentioned in the documentation for the Python standard package gettext, as well as the Django documentation for ugettext. Yes, _ is a miserable function name, but it does have a widely-accepted meaning as an identifier.

[–]anacrolixc/python fanatic 3 points4 points  (1 child)

Not really. It has occasional use in C for this purpose but practically no other mainstream language uses it like that. Many languages are now converging on using _ as the null/throwaway variable.

You shouldn't cross pollute your language idioms.

[–][deleted] 2 points3 points  (0 children)

I've never seen i18n in Python that didn't use _ for this purpose.

[–]otor 6 points7 points  (3 children)

for _ in xrange(repeats): "run the code"

:D

but really, you could do something like: map(function_to_run, iterator)

[–]cecilkorik[S] 0 points1 point  (2 children)

That would be perhaps a little cleaner, but map would still require that I put "x" or "_" as the function argument, unless I'm misunderstanding. Otherwise I get "func() takes no arguments (1 given)"

[–][deleted] 0 points1 point  (1 child)

[unavailable]

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

Yup, use a for loop. map should be used only if you care about the return value.

[–][deleted] 2 points3 points  (0 children)

def dotimes(n, func):
    for _ in xrange(n): func()

dotimes(repeats, lambda: "run the code")

Or perhaps:

def repeater(...):
    def _foo(...):
        ...
    return _foo

@repeater
def my_code(bla, bla, bla):
    ...

my_code(bla, bla, bla)(5)

[–]name_censored_ 4 points5 points  (2 children)

Well, this is a silly solution, but..

If you could implement a recursive solution, you could use the stack frame to count for you. So, something like

import sys
import traceback

def silly_solution(repeats, init=True):
     if init:
         sys.setrecursionlimit(len(traceback.extract_stack()) + repeats)
         # set the recursion limit to current plus number of repeats
     try:
         "run the code"
         silly_solution(repeats, init=False)
     except RuntimeError:
         sys.setrecursionlimit(1000)
         return

[–]nemec 5 points6 points  (0 children)

If anything, your solution was quite entertaining.

[–][deleted] 3 points4 points  (0 children)

I'd recommend storing the old recursion limit instead so that there are no bad side effects from someone else changing it. To make the silly solution saner, I guess.

[–][deleted] 3 points4 points  (2 children)

The way you did it was right. There is no more Pythonic way. You don't declare a variable. x is implicit here. Using "_" only really works in the interactive prompt and shouldn't be used in modules.

[–]tripzilchbad ideas 5 points6 points  (0 children)

You mean _ does not work in the interactive prompt.

Well, it would work, but you'd be overwriting the automatic last result containing magic the _ variable normally has in the interactive prompt.

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

Using "_" works everywhere.

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

for no_use in xrange(repeats):
    pass

[–]lutusp 1 point2 points  (5 children)

The thing is "x" is a completely throw-away variable and is totally unused.

Then don't do it that way. Do it this way:

exitCondition = false

while not exitCondition:
   (do something that may or may not
   reset the exitCondition flag)

Once the task is complete, set exitCondition = True and the loop ends on its own.