我有一个文件列表,如果列表中没有给定的文件名,则需要设置一个标志。所以我有:
if all('FileName' not in f for f in files):
# set flag
我想扩展此检查以查找多个文件名,因此我创建了一个文件名列表:
file_names = ['FileName', 'FileName2']
在psuedo代码中,我正在寻找:
if all(#all file names in files_names# not in f for f in files):
# set flag
我还能以某种方式使用内置的所有功能来实现这一点吗?或者我需要将它分成多个语句吗?
感谢您的帮助。
答案 0 :(得分:5)
如果我理解正确的话......一种方法是将两者都转换成集:
files = set(files)
file_names = set(file_names)
if not file_names <= files:
# set flag
请注意,<=
是子集运算符(.issubset
的快捷方式)。
编辑如果要检查所有文件是否都在files
中,那么您可以使用交叉点运算符&
(或.intersection
方法)来检查两组中是否有共同元素:
if not file_names & files:
# set flag
如果要保留列表结构,则可以使用临时转换:
if not set(file_names) & set(files):
# set flag
# file_names is still a list
该解决方案不仅优雅而且高效。在这里阅读更多关于集合的内容:
http://docs.python.org/2/library/sets.html
编辑2 如果您想检查file_names
中的名称是否包含 <(与我的解决方案不同,我只检查名称之间的严格相等)在files
的名称中,您可以使用此:
if all(all(name not in fn for fn in files) for name in file_names):
# set flag
与您编写的伪代码非常相似。它展示了Python的美妙之处。 :D在这种情况下,使用集合并不重要。
答案 1 :(得分:0)
如果您想继续以列表形式对它们进行操作,您实际上可以避免将它们作为集合单独投射,例如:
if not set(file_names).issubset(files):
# set flag
type(file_names)
仍会返回:
<type 'list'>
答案 2 :(得分:0)
似乎您第一次使用all()
是不必要的,因为看起来您只需要:
if 'FileName' not in files:
#set flag
然而,您提出的新问题可能会受益于all()
或取决于您希望实现的目标(all()
的输出可能有点欺骗)您也可以使用any()
根据{{3}} all()
实际
如果迭代的所有元素都为真(或者如果是),则返回[s]为真 iterable是空的)
这意味着如果你有一个&#39;文件名&#39;并且您正在检查以下方案存在的files
列表
# all file names present in files
file_names = ['file','file1','file2']
files # with files ['file','file1','file2','filen']
not all(f in files for f in file_names) #False
和
# no file names to be compared against
file_names = []
files # with files ['file','file1','file2','filen']
not all(f in files for f in file_names) # True
和
# some file names not present in files
file_names = ['file','foo','bar','baz']
files # with files ['file','file1','file2','filen']
not all(f in files for f in file_names) # True
您会注意到最后两个是相同的,在这些含糊不清的情况下,我更喜欢使用any()
documentation
如果iterable的任何元素为true,则返回True。如果iterable为空,则返回False。
这样
# all file names present in files
file_names = ['file','file1','file2']
files # with files ['file','file1','file2','filen']
any(f not in files for f in file_names) # False
和
# no file names to be compared against
file_names = []
files # with files ['file','file1','file2','filen']
any(f not in files for f in file_names) # False
和
# some file names not present in files
file_names = ['file','foo','bar','baz']
files # with files ['file','file1','file2','filen']
any(f not in files for f in file_names) # True
这意味着您不必执行任何其他逻辑来确定files
是否为空。但是,这是一个边缘情况,您似乎可以控制files
包含的内容,因此any()
或all()
就足够了。
在扩展的情况下,你要检查你的file_name
是否包含在列表中文件的名称中(这很有趣),然后作为#freakish声明你可以嵌套{{ 1}}或any()
语句
all()
虽然这适用于您的情况,但我认为更有用且更性感的中途documented倒置版本
all(all(name not in fn for fn in files) for name in file_names):
# set flag
为什么它更实用?因为简单地取出all(not any(name in file for file in files) for name in file_names)
现在允许另一个有用的问题:我看到的任何文件是否存在?