简体   繁体   English

使用地图移动文件(shutil.move)

[英]Move files with map(shutil.move)

I'd like to move following books to specified DirHTML directory. 我想将以下书籍移至指定的DirHTML目录。

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: 可以使用以下代码轻松将它们移动到DirHTML

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. 首先让我这样说:您可以通过这种方式使用map ,但是我认为这不是一个好主意。 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. 当用于副作用时,就像您所做的那样,IMO更加清楚了原始命令性代码。

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; Tripleee显示了一些解决方案/解决方法; 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. 其次,如果您使用的是Python 3:则地图是惰性的。 It only evaluates its result when you iterate over it. 它仅在迭代时评估其结果。 For example, you could pass the result to list() : 例如,您可以将结果传递给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. 提示:在shutil.move周围写一个小包装,以打印其参数,以更好地了解发生了什么。

from the official python doc here 这里的官方python文档

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: 在您的map片段中,它将充当:

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. DirHTML参数的工作与您期望的一样,将整个字符串传递给move但是依次传递了每个字符。

Each argument to map after the first should be an iterable . 在第一个参数之后map每个参数都应该是iterable Indeed, 'DirHTML' is an iterable, but iterating it obtains ['D', 'i', 'r', 'H', 'T', 'M', 'L'] which is obviously not what you want. 确实, 'DirHTML' 可迭代的,但是对其进行迭代可以获得['D', 'i', 'r', 'H', 'T', 'M', 'L'] ,这显然不是您想要的。

If you insist on using map here, try 如果您坚持要在这里使用map ,请尝试

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. 两者都不是特别透明或优雅的,在后一种情况下,不必要地效率低下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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