Python Forum
Simple script to find directories containing pictures
Thread Rating:
  • 3 Vote(s) - 3.33 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Simple script to find directories containing pictures
#1
I'm relatively new to python, just a couple of months into learning, but I wanted to share this, because I thought it was wickedly cool.

I had a problem today and thought it was a good chance to practice some python.

I want to make sure all the photos on my PC are backed up online, so I wanted to write a script just to find all directories on my external hard drive that contain pictures (just jpegs).

I come from a C++ background, so I started writing for loops to iterate the directories and files, but I thought, "there's got to be a better way."

I started searching and testing some code, and I whittled it down to just 5 lines of actual code, and only 1 of those is doing any real work!

It was just cool to see how powerful the language is, and I know this is just a simple task for python. 

Here's what I ended up with:

import os

cur_dir = os.path.dirname(os.path.realpath(__file__))

dirs_with_pics = [root for root, dirs, files in os.walk(cur_dir) if any(map(lambda f: f.endswith(".jpg"), files))]

for dir in dirs_with_pics:
    print(dir)
The script file is located in the root directory of my external hard drive so that __file__ would just work.

Still learning, so please comment if there are better or more "pythonic" ways to do this.
Reply
#2
You might want to checkout glob :)
Reply
#3
You need glob - http://stackoverflow.com/a/3964691/6212957
Reply
#4
No glob is not needed,and glob is  the wrong tool for this task it dos not recursively search sub folders as os.walk() dos.
After PEP-471 os.walk() has got faster Python 3.5 or newer.
Quote:In practice, removing all those extra system calls makes os.walk() about 8-9 times as fast on Windows ,
and about 2-3 times as fast on POSIX systems . So we're not talking about micro- optimizations.


Quote:Still learning, so please comment if there are better or more "pythonic" ways to do this.
It's an okay solution,the list comprehensions can be a little long so get  harder to read with when also put in map lambda.
It's not necessary to make a list,then loop over that list.
So can write it like this:
import os

cur_dir = os.path.dirname(os.path.realpath(__file__))
for root,dirs,files in os.walk(cur_dir):
    if any(f for f in files if f.endswith(('.jpg', '.png'))):
        print(root)
endswith(() can also take a tuple as argument,so can search from more file extensions.
Reply
#5
(Apr-24-2017, 03:50 AM)snippsat Wrote: No glob is not needed,and glob is  the wrong tool for this task it dos not recursively search sub folders as os.walk() dos.
Actually, as of 3.5, glob does support recursive searching. Not sure about performance comparisons. But I suspect (though haven't written it to check) that the code would be simpler.
Reply
#6
(Apr-24-2017, 05:34 AM)micseydel Wrote: Actually, as of 3.5, glob does support recursive searching.
Okay thanks for info.
I see in doc that is set like this.
glob.glob('**/*.txt', recursive=True)

Quote:But I suspect (though haven't written it to check) that the code would be simpler.
I doubt that code could be simpler,
because in his task he need to know in which root folder that has images.
glob only return file names or sub folder name with file name 'sub/img.jpg'.
glob dos not store info about absolute path root folder as os.walk() dos.
Reply
#7
You can get the whole path with os.path.abspath('sub/img.jpeg')

But glob.glob() uses os.listdir instead of os.scandir. So os.walk could be faster.
The if statement for checking the file extensions should not slow it down so much
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#8
(Apr-22-2017, 09:26 PM)micseydel Wrote: You might want to checkout glob :)

I saw some references to glob as I was putting together that script, but I didn't investigate it at the time. 

But since multiple people mentioned it here, I'll check it out.

Thanks.

(Apr-24-2017, 03:50 AM)snippsat Wrote: It's an okay solution,the list comprehensions can be a little long so get  harder to read with when also put in map lambda.
It's not necessary to make a list,then loop over that list.

That's a good point. Since I ended up looping over the list to print it out anyway, I guess there wasn't much benefit to using a list comprehension in this situation.

I think part of me wanted to see if I could do it all in one line  Wink
Reply
#9
In [1]: l = list(range(1, 11))

In [2]: _ = [print(n**3) for n in l]
1
8
27
64
125
216
343
512
729
1000
_ is used because print() will return None and you will get a list filled with None.
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Just a simple vshare.io api script Aqua22 5 4,207 May-11-2020, 04:34 PM
Last Post: buran

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020