简体   繁体   中英

Move files with map(shutil.move)

I'd like to move following books to specified DirHTML directory.

books = ['HTML-Head First HTML and CSS - 2nd Ed.pdf',
 'HTML and CSS - Design and Build Websites - Jon Duckett - November 2011.pdf',
 "Murach's HTML5 and CSS3 3rd Edition (2015).pdf",
 'HTML5-cheat-sheet.pdf']

Easily they can be moved to DirHTML with codes:

import shutil
for book in books:
    shutil.move(book, 'DirHTML')

When I tried

map(shutil.move, books, 'DirHTML')

There's no files moved. How to enable the code working?

First let me say this: you can use map this way, but I don't think it's a good idea. It's meant to transform iterables, not to have side effects. When used for the side effects, as you do, the original imperative code is IMO much clearer.

Now, if you insist to use map, read on. There are potentially two issues here.

First, as explained in other answers, you can't pass the destination directory the way you do. tripleee shows some solutions/workarounds; here's another one:

from functools import partial
map(partial(shutil.move, dst='DirHTML'), books)

Second, if you're using Python 3: map is lazy. It only evaluates its result when you iterate over it. For example, you could pass the result to list() :

list(map(partial(shutil.move, dst='DirHTML'), books))

Tip: write a little wrapper around shutil.move that prints its arguments, to better see exactly what's going on.

from the official python doc here

If additional iterable arguments are passed, function must take that many arguments and is applied to the items from all iterables in parallel

In your map snippet, it will act as:

for i, j in zip(books, 'DirHTML'):
    shutil.move(i, j)

the DirHTML argument is as work as you expected passed whole string into move but pass each character in sequence.

Each argument to map after the first should be an iterable . Indeed, 'DirHTML' is an iterable, but iterating it obtains ['D', 'i', 'r', 'H', 'T', 'M', 'L'] which is obviously not what you want.

If you insist on using map here, try

map(lambda x: shutil.move(x, 'DirHTML'), books)

or maybe

map(shutil.move, books, ['DirHTML'] * len(books))

neither of which is particularly transparent or elegant, and in the latter case, unnecessarily inefficient.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM