Would you please explain why this Python code works to a C programmer?
This idiom works to retrieve a file list, recursively
[os.path.join(dp, f) for dp, dn, fn in os.walk(os.path.expanduser(dir)) for f in fn]
I found that style here in Recursive os.listdir?. It has no punctuation, or nesting. I can't understand why it works. Can you write same in a more tedious style that I can understand so that I don't feel so helpless? :)
People usually say "give us an example of why you use that", and I'll show you the whole program. I was so stunned it worked at all I blogged about it, with a picture http://pj.freefaculty.org/blog/?p=285
That's for Ubuntu 14.10 with the XFCE4 desktop and the Compiz window manager/compositor. It will replace background wallpapers on the viewports by interacting with Dconf through gsettings.
The usage I don't understand is inside random.choice() below:
#!/usr/bin/env python3
import argparse
import subprocess
import sys
import os
import random
parser = argparse.ArgumentParser()
parser.add_argument("-d", "--dir", help = "directory path",
default = "/usr/local/share/Backgrounds")
parser.add_argument("-w", "--workspace",
help = "workspace number, 0, 1-n, or > n", default = "-1",
type = int)
parser.add_argument("-schema", help = "gsettings shema",
metavar = "SCHEMA", default = "org.compiz.wallpaper:/org/compiz/profiles/Default/plugins/wallpaper/")
parser.add_argument("-key", help = "gsettings key", metavar = "KEY", default = "bg-image")
args = parser.parse_args()
array = eval(subprocess.check_output(["gsettings", "get", args.schema, args.key]))
## print(array)
arraylen = len(array)
filename = random.choice([os.path.join(dp, f) for dp, dn, fn in os.walk(os.path.expanduser(args.dir)) for f in fn])
print("The newly found filename is:")
print(filename)
ws = args.workspace - 1
## If ws 0 or smaller, we are going to reset whole collection back to
## just one image. if ws > N of images, then add a new image.
if ws < 0:
array=[str(filename)]
subprocess.call(["gsettings", "set", args.schema, args.key, str(array)])
subprocess.call(["gsettings", "set", args.schema, "bg-fill-type", str("[0]")])
subprocess.call(["gsettings", "set", args.schema, "bg-image-pos", str("[0]")])
subprocess.call(["gsettings", "set", args.schema, "bg-color1", str("['#000000ff']")])
subprocess.call(["gsettings", "set", args.schema, "bg-color2", str("['#000000ff']")])
elif ws < arraylen:
array[ws]=str(filename)
subprocess.call(["gsettings", "set", args.schema, args.key, str(array)])
else:
array.append(str(filename))
subprocess.call(["gsettings", "set", args.schema, args.key, str(array)])
arraylen = len(array)
subprocess.call(["gsettings", "set", args.schema, "bg-fill-type", str([0]*arraylen)])
subprocess.call(["gsettings", "set", args.schema, "bg-image-pos", str([0]*arraylen)])
subprocess.call(["gsettings", "set", args.schema, "bg-color1", str(['#000000ff']*arraylen)])
subprocess.call(["gsettings", "set", args.schema, "bg-color2", str(['#000000ff']*arraylen)])
subprocess.call(["gsettings", "set", args.schema, args.key, str(array)])
print("HELLO, corrected image array is:")
print('\n '.join(array))
If you say "we don't understand what you don't understand," I get it. Here are some specific questions I want to ask
- Why is there no bracket around dp, dn, fn
- The for statement at the end "for f in fn" has no statements "inside it".
- How does os.path.join(dp, f) work when dp and f don't exist before that statement?
I get the same allergic feeling in Perl when people put an if statement and the end of a line, rather than at the beginning.