14

<edit> Thanks to everyone who has answered so far. The zip and os.path.join are really helpful. Any suggestions on ways to list the counter in front, without doing something like this:

zip(range(len(files)), files, directories)

</edit>

Hi,

I'm in the process of learning Python, but I come from a background where the following pseudocode is typical:

directories = ['directory_0', 'directory_1', 'directory_2']
files = ['file_a', 'file_b', 'file_c']

for(i = 0; i < directories.length; i++) {
    print (i + 1) + '. ' + directories[i] + '/' + files[i] + '\n'
}

# Output:
# 1. directory_0/file_a
# 2. directory_1/file_b
# 3. directory_2/file_c

In Python, the way I would write the above right now, would be like this:

directories = ['directory_0', 'directory_1', 'directory_2']
files = ['file_a', 'file_b', 'file_c']

for i in range(len(directories)):
    print '%s. %s/%s' % ((i + 1), directories[i], files[i]

# Output:
# 1. directory_0/file_a
# 2. directory_1/file_b
# 3. directory_2/file_c

While reading Dive into Python, Mark Pilgrim says that using for loops for counters is "Visual Basic-style thinking" (Simple Counters). He goes on to show how to use loops with dictionaries, but never really addresses a python solution in regards to how for loop counters are typically used in other languages.

I was hoping somebody could show me how to properly write the above scenario in Python. Is it possible to do it a different way?

If I took out the incrementing line count, is it possible to just match the two lists together using some kind of list comprehension?

For example, if all I wanted from the output was this (no counters, is that possible with list comprehension):

# Output:
# directory_0/file_a
# directory_1/file_b
# directory_2/file_c

Thanks in advance for any help.

3
  • i added an example with counter Commented Feb 6, 2009 at 18:25
  • May I suggest that those are "lists" not "arrays", it's a small point.
    – Ali Afshar
    Commented Feb 6, 2009 at 18:26
  • @SilentGhost Thanks a lot , I've marked your answer as the accepted answer. I appreciate the help! @Ali A Good point, I updated my post to says "lists" rather than "arrays".
    – agraddy
    Commented Feb 6, 2009 at 19:00

4 Answers 4

36
import os.path
for dir, file in zip(directories, files):
    print(os.path.join(dir, file))                      # for directories, files

you can have it as a list comprehension as well, creating list of string with print going after that]

with counter:

for i, (dir, file) in enumerate(zip(directories, files)):
    print(i, os.path.join(dir, file))
2
  • Thanks for the answer! The os.path.join is really helpful. Any recommendation on how to get the counters in front?
    – agraddy
    Commented Feb 6, 2009 at 18:04
  • Look up itertools.count() or use enumerate(), as in other answers.
    – hughdbrown
    Commented Feb 16, 2012 at 13:33
10

Try this:

directories = ['directory_0', 'directory_1', 'directory_2']
files = ['file_a', 'file_b', 'file_c']

for file, dir in zip(files, directories):
    print dir + '/' + file

To explain, the zip() function takes lists as input and returns a list of "zipped" tuples. so zip([1,2,3,4,5],[a,b,c,d,e]) would return [(1,a),(2,b) and so on.

You can then assign the members of the tuples to variables with the python for <var> in <list> syntax.

There are a million different ways to do what you are asking, but the above uses some more "pythonic" constructs to make the code a lot more readable (IMHO, anyway).

1
  • Wow, the zip function is great! Any recommendation on how to get the counters in front without doing something like this zip(range(len(files)), files, directories)?
    – agraddy
    Commented Feb 6, 2009 at 18:01
1

If you want to add a counter to any for loop in Python you can use the enumerate() function:

listA = ["A", "B", "C", "D", "E"]
listB = ["a", "b", "c", "d", "e"]
for i, (a, b) in enumerate(zip(listA, listB)):
    print "%d) %s, %s" % (i, a, b)

gives the output:

0) A, a
1) B, b
2) C, c
3) D, d
4) E, e
0
-1

Building on Ryan's answer, you can do:

for fileDir in [dir + '/' + file for dir in directories for file in files]:
    print(fileDir)
3
  • This gives the cross product of the files and directories (n² lines instead of n).
    – Ben Blank
    Commented Feb 6, 2009 at 18:00
  • Ah. I misread the question and thought that was what he wanted. You are correct. Commented Feb 6, 2009 at 18:09
  • Although it didn't solve the problem, it did give me something to think about - thanks for the response.
    – agraddy
    Commented Feb 6, 2009 at 19:08