1

I am noob and trying to understand Python.

For os.walk documentation says that it returns a tuple (dirpath, dirnames, filenames)

just of understanding I am trying to use it like below

import os
from os.path import join, getsize
file=[]
dir=[]
xroot,dir,file = os.walk('C:\Python27\mycode')

But it gives me error like : xroot,dir,file = os.walk('C:\Python27\mycode') ValueError: need more than 2 values to unpack

My question is why cant I assign it like above rather then it being part of loop (most example use that)?

jamylak
  • 128,818
  • 30
  • 231
  • 230
x0rcist
  • 23
  • 1
  • 5
  • There are multiple files in the directory (seems like two from your error message). When you use it in a loop, then you get (xroot,dir,file) for each file in the directory. – Jim Garrison Jun 05 '13 at 05:53

3 Answers3

2

Your code attempts to unpack the generator returned by os.walk() into a three-tuple. This is fine, but the problem is that the generator yields only two items, which isn't going to work.

Each item in the generator is a three-tuple itself, which is what your for loop is really unpacking each iteration. A more verbose way of writing it would be:

for three_tuple in os.walk('C:\Python27\mycode'):
    xroot, dir, file = three_tuple

You might find it easier to actually turn that generator into a list:

>>> pprint.pprint(list(os.walk('.')))
[('.', ['foo'], ['main.py']),
 ('.\\foo', [], ['test.py', 'test.pyc', '__init__.py', '__init__.pyc'])]

As you can see, the result is an iterable (a list) where each element is a three-tuple, which can then be unpacked into a root folder, a list of folders and a list of files.

Blender
  • 289,723
  • 53
  • 439
  • 496
1

os.walk returns an iterator. The usual think to do is loop over it

for xroot, dir, file in os.walk('C:\Python27\mycode'):
    ...

but you can also just use xroot, dir, file = next(os.walk('C:\Python27\mycode')) to single step through

John La Rooy
  • 295,403
  • 53
  • 369
  • 502
1

os.walk does not return root,dir,file. it returns a generator object for the programmer to loop through. Quite possibly since a given path might have sub-directories, files etc.

>>> import os
>>> xroot,dir,file = os.walk('/tmp/') #this is wrong.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack
>>> os.walk('/tmp/')
<generator object walk at 0x109e5c820> #generator object returned, use it
>>> for xroot, dir, file in os.walk('/tmp/'):
...     print xroot, dir, file
... 
/tmp/ ['launched-IqEK']
/tmp/launch-IqbUEK [] ['foo']
/tmp/launch-ldsaxE [] ['bar']
>>> 
Srikar Appalaraju
  • 71,928
  • 54
  • 216
  • 264
  • The SO thread on generators: http://stackoverflow.com/questions/231767/the-python-yield-keyword-explained/231855#231855 – theodox Jun 05 '13 at 06:10