2

Context: I'd like to specify the names of a bunch of directories that I want my script to make. I'd like to declare these path names as variables and add them to a list, which I will iterate over to make the directories. Python 2.7.5.

I'm trying the following:

dir_list = [
(dir_1 = "<path_to_dir_1>")
(dir_2 = "<path_to_dir_2>")
]

And I get:

    (dir_1 = "<path_to_dir_1>"),
           ^           
SyntaxError: invalid syntax

If I do:

dir_1 = "<path_to_dir_1>"
dir_2 = "<path_to_dir_2>"
dir_list = [dir_1, dir_2]
print dir_list

It works fine without an error.

I have searched and did not find an answer to this question, though I did find an answer to how to format multi-line dictionaries in Python: What is the proper way to format a multi-line dict in Python?

And the PEP8 style-guide offers guidance on how to format multi-line lists as well: https://www.python.org/dev/peps/pep-0008/#indentation

However, I have not found an answer to whether I can collapse variable assignment and list inclusion into one step.

Community
  • 1
  • 1
phoenixdown
  • 828
  • 1
  • 10
  • 16

6 Answers6

1

I think the short answer is No. In Python 2.7, an assignment statement is a statement, so cannot be included in the context of a list element. There may be a way to unpack a list into other variables, but not exactly as you state. I look forward to the real Python experts weighing in :) .

cxw
  • 16,685
  • 2
  • 45
  • 81
1

No. An assignment is not an expression (it doesn't evaluate to anything), so you cannot simultaneously assign to a variable and insert into a list.

mipadi
  • 398,885
  • 90
  • 523
  • 479
1

This is just not possible since what you are trying to do will be considered as an assignment:

Python evaluates expressions from left to right. Notice that while evaluating an assignment, the right-hand side is evaluated before the left-hand side.

from 5.14 Evaluation order

so that every expression that is at the right of the assignment operand = will be evaluated before the left side and yours is formally a syntax error.

loretoparisi
  • 15,724
  • 11
  • 102
  • 146
1

Without full context of your situation, my preference is to keep it simple.

dir_1 = '<path_to_dir_1>'
dir_2 = '<path_to_dir_2>'
dir_list = [dir_1, dir_2]
print dir_list

However, as you've explicitly rejected this, my next choice is a dict

dir_dict = dict(
    dir_1='<path_to_dir_1>',
    dir_2='<path_to_dir_2>',
)
print dir_dict.values()

You seem not to like dicts either, so I will offer this monstrosity that abuses locals(), but I strongly advise against it.

dir_1 = '<path_to_dir_1>'
dir_2 = '<path_to_dir_2>'
dir_list = [path for name, path in locals().items() if name.startswith('dir_')]
print dir_list

Python is all about simplicity (and dictionaries) so I'd say embrace them.

One last alternative: you could create a dictionary subclass that allows attribute access of its keys. This means fewer quotes around path names.

class PathCollection(dict):
    def __init__(self, *args, **kwds):
        super(PathCollection, self).__init__(*args, *kwds)
        self.__dict__ = self

paths = PathCollection()
paths.dir_1 = '<path_to_dir_1>'
paths.dir_2 = os.path.join(paths.dir_1, '<relative_to_path_dir_2>')
print paths.values()
matt
  • 1,895
  • 5
  • 19
  • 26
0

you can deal it with dict:

dir_list = [
    {"dir_1" : "<path_to_dir_1>",
     "dir_2" : "<path_to_dir_2>"}
]

and if it's must to use list, you can't declare a variable like you did, you can only do this:

dir_list = ["<path_to_dir_1>", "<path_to_dir_2>"]
omri_saadon
  • 10,193
  • 7
  • 33
  • 58
0

Your code is confusing, but I don't think you need a dict, you just need a list of paths, which goes like this:

dir_list = ['c:/users/me/hi', 'c:/users/you/hi', ...]

Then you can iterate over it:

for path in dir_list:
    os.mkdir(path) #or os.mkdirs(path), check the usage

If you want to name each path, you can use a dict however:

dir_dict = {'me': 'c:/users/me/hi', 'you': 'c:/users/you/hi'...}

Which you can then iterate through by the key names:

for name in dir_dict.keys():
    path = dir_dict[name]
    os.mkdir(path)

Then you could incorporate those names in somehow.

Edit: If you wanted to, for example, build from a source like this:

source = [('name', 'c:/path/%s'), ('you', 'c:/otherpath/%s'), ('him', 'c:/yetanotherpath/%s')]

dir_paths = dict()
for elem in source:
    dir_paths[elem[0]] = elem[1] % (elem[0])

dir_paths
> {'him': 'c:/yetanotherpath/him',
   'name': 'c:/path/name',
   'you': 'c:/otherpath/you'}

I'm not clear on how you're building your list of paths and names - is there some process, or are you just typing a bunch in?

Jeff
  • 2,158
  • 1
  • 16
  • 29
  • You're right, I don't need a dict - which is why I'm not making one. I do want the directories to have variable names - what if someone comes along later and wants to change the on-disk location of a directory that still logically points to the same resource? Variable name maintains the logical connection while permitting assignment of a new physical location. The benefit is separation of physical and logical layers. – phoenixdown Jun 28 '16 at 18:29
  • 1
    If you want to name the paths for future reference, a dictionary is what you need. Your first bit of code with the syntax error looks exactly like creating a dictionary. Or if the order matters for you the way a list maintains, you can use an ordereddict from collections. – Jeff Jun 28 '16 at 18:37
  • If I use a dict can I do the assignment at the same time as insertion into the dict? So: dir_dict = {'me': 'c:/user/me', 'my stuff': '%s' %(me + '/mystuff') } 'my stuff' should evaluate to: 'c:/user/me/mystuff' Is that what you mean? – phoenixdown Jun 28 '16 at 19:02
  • I'll add something to my answer. – Jeff Jun 28 '16 at 20:01
  • Typing a bunch in :( EDIT: like this - dir_1 = "/dir1", dir_2 = dir_1 + "/dir2", etc. there are lots of these, they are not all linear (otherwise i'd do one os.makedirs and be done with it) etc. – phoenixdown Jun 28 '16 at 20:03