Notts90
Notts90

Reputation: 255

Is there any significance of the triple underscores in this python for loop?

Is there any significance in the triple underscore in Python?

This was in a script for getting all .txt files in a directory.

for ___,___,files in os.walk(some_folder):
    files[:]=[x for x in files if x.lower().endswith('txt')]
    for file in files:

Reading other questions on here a single underscore is normally used for throw away variables, is this use of a triple underscore just bad practice or is there significance to it?

Upvotes: 4

Views: 2201

Answers (3)

mykhal
mykhal

Reputation: 19924

Is there any significance in the triple underscore in Python?

A note to ___ being used elsewhere (not much related to your question title / code sample, or bare Python):

This variable contains 3rd last value in interactive IPython/jupyter shell (unless it was overwritten e.g. like in your example).

In [1]: "hello"
Out[1]: 'hello'

In [2]: f"{_} world"
Out[2]: 'hello world'

In [3]: f"{__} {_}!"
Out[3]: 'hello hello world!'

In [4]: (_, __, ___)
Out[4]: ('hello hello world!', 'hello world', 'hello')

Upvotes: 1

Dimitris Fasarakis Hilliard
Dimitris Fasarakis Hilliard

Reputation: 160557

Single, double, triple and, in general, any amount of underscore only names in a script implicitly signifies that the value will not be used (the fact that it isn't given a "name" using any letters signifies this).

This is, of course, not set in stone (that is, Python doesn't treat ___ any differently than a name like foo) instead it's a convention programmers usually understand and respect.

The single underscore has a purpose only in interactive mode and it's the one that's employed in scripts instead of __ or ___. Using ___ and __ just look ugly and really are completely unecessary; I can't see why someone would decide to use it over _; don't copy them and opt for _ when you need to get the same message across.

Upvotes: 6

boot-scootin
boot-scootin

Reputation: 12515

Like Jim said, the ___ syntax usually means whatever is captured by that name (___) isn't useful, or is garbage. Take a look at the following example, for the sake of completeness:

I have a folder, test, with the following structure:

test
    subtest1
        file1.txt
        file2.txt
    subtest2
        file3.txt

Look what happens when I use os.walk on test:

>>> list(os.walk('test'))
[('test', ['subtest1', 'subtest2'], ['.DS_Store']), ('test/subtest1', [], ['file1.txt', 'file2.txt']), ('test/subtest2', [], ['file3.txt'])]
>>> len(list(os.walk('test')))
3

So there are technically three elements in the generator returned by os.walk('test'). How many elements are within each element, though, since we clearly see some nested data structures?

>>> [len(x) for x in os.walk('test')]
[3, 3, 3]

Okay, there are three subelements in each element of os.walk('test'). For example, at list(os.walk('test'))[0], there is 'test' (the first element), ['subtest1', 'subtest2'] (the second element), and ['.DS_Store'] (the third and final element). The last element contains the non-directory files in whatever folder is denoted by the first element (so .DS_Store is a file in the test directory).

Let's get to your for loop, then (I won't use the underscores yet):

>>> for main_dir, sub_dirs, files in os.walk('test'):
...         print("Main directory: ", main_dir)
...         print("Sub-directories: ", ', '.join(sub_dirs))
...         print("Files: ", ', '.join(files))
... 
Main directory:  test
Sub-directories:  subtest1, subtest2
Files:  .DS_Store
Main directory:  test/subtest1
Sub-directories:  
Files:  file1.txt, file2.txt
Main directory:  test/subtest2
Sub-directories:  
Files:  file3.txt

So the for main_dir, sub_dirs, files in os.walk('test') syntax is really what we call "unpacking." We are assigning to main_dir the first element in os.walk('test'), to sub_dirs the second element, etc. The ___ syntax (which really should be just _), says to the reader, "Forget about these values; I've named the ones I need." In your case, the code is saying, "Forget about the directories from which these files come; I just want the filenames themselves."

Upvotes: 3

Related Questions