微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Python:函数字符串变量中的For循环

如何解决Python:函数字符串变量中的For循环

我是 Python 初学者,在学习了数月的理论、阅读 Python 书籍和在线 udemy 课程后,我试图自己构建我的第一个项目。

我有一个带有 for 循环的函数,它使用 os.walk 来查找所有视频(电视节目)文件。我晚点

VIDEO_EXTENSIONS = ('.wmv','.avi','.mkv','.mp4','.mpg','.mpeg','.mov')
  
def vid_file():
    for root,subdir,files in os.walk(root_path):
        for video_filename in files:
            if video_filename.endswith(VIDEO_EXTENSIONS):
                print(video_filename)

如果我调用这个函数,我会得到 root_path 中的所有视频文件,但它不是字符串类型,它的 . vid_file() 的输出类似于:

tv.show.s01e01.episode.name.mkv
tv.show.s01e02.episode.name.mkv

当尝试使用正则表达式来拆分文件的季节信息时,它不起作用,因为它不是字符串。

print(re.split(season,vid_file()))

错误

    Traceback (most recent call last):
  File "./re_org.py",line 60,in <module>
    print(re.split(season,vid_file()))
  File "/usr/lib/python3.8/re.py",line 231,in split
    return _compile(pattern,flags).split(string,maxsplit)
TypeError: expected string or bytes-like object

好的没问题。在函数 vid_file() 中,我想我只是将“print()”更改为“return video_filename”。 这将起作用,但仅适用于 1 个文件,而不适用于 vid_file() 函数的 for 循环中找到的所有文件

season = re.compile(r'S\d+')    
print(re.split(season,vid_file()))

输出

['tv.show.','e06.episode.name.mkv']

我觉得我缺少一些关于 for 循环和函数如何工作的东西,但不知道是什么。感谢您对前进的最佳方式的任何帮助以及对其工作原理的解释。

解决方法

如果我正确理解您的要求,请您尝试:

import os

VIDEO_EXTENSIONS = ('.wmv','.avi','.mkv','.mp4','.mpg','.mpeg','.mov')

def vid_file(dir):
    for root,subdir,files in os.walk(dir):
        for video_filename in files:
            if video_filename.endswith(VIDEO_EXTENSIONS):
                yield os.path.join(root,video_filename)

root_path = "."           # or wherever you want
l = list(vid_file(root_path))
print(l)

函数 vid_file() 返回一个生成器,列表 l 包含视频文件列表。

,

我觉得我缺少一些关于如何 for 循环和函数的信息 工作,但不知道做什么。

您需要返回 an iterable 与函数执行的结果(列表、生成器等)

来自docs

事实上,即使没有 return 语句的函数也会返回一个值, 虽然是一个相当无聊的。这个值叫做 None(它是一个内置的 名称)。写入值 None 通常被抑制 解释器,如果它是唯一写入的值。

def a():
    pass

def b():
    return

def c():
    return ['file1','file2']

def d():
    for f in ['file1','file2']:
        print(f,end=" ")

print(a()) # None
print(b()) # None
print(c()) # ['file1','file2']
print(d()) # file1 file2 None

您正在使用一个需要字符串并得到 None 的拆分函数。

print(re.split(season,vid_file()))

来自docs

re.split(pattern,string,maxsplit=0,flags=0)

根据出现的模式拆分字符串。

print(re.split(pattern=season,string=vid_file()))

在函数 vid_file() 中,我只需将 'print()' 更改为 'return video_filename'。

如果你这样做...

if video_filename.endswith(VIDEO_EXTENSIONS):
    return video_filename # return one file

这意味着一旦找到第一个匹配的文件就退出循环。


代码示例:

import os
import re
from typing import Tuple,List # optional


VIDEO_EXTENSIONS = ('.wmv','.mov')
season = re.compile(r's\d+')

def vid_file():
    for root,files in os.walk('.'):
        for video_filename in files:
            if video_filename.endswith(VIDEO_EXTENSIONS):
                print(video_filename)

 
result = vid_file() # prints filenames,return None
print(result) # None
print(type(result)) # <class 'NoneType'>

# TypeError: expected string or bytes-like object:
# print(re.split(season,result))


def vid_file(extensions: Tuple[str]) -> List[str]:
    result = []
    for root,files in os.walk('.'):
        for video_filename in files:
            if video_filename.endswith(extensions):
                # add filename to list
                result.append(video_filename)

    return result


result = vid_file(VIDEO_EXTENSIONS) # return list with filenames
print(result)
print(type(result)) # <class 'list'>
print(type(result[0])) # <class 'str'>

# suppose we found matching files
files = [
    'tv.show.s01e01.episode.name.mkv','tv.show.s01e02.episode.name.mkv'
    ]

for f in files: # f is a string
    print(re.split(season,f))

# ['tv.show.','e01.episode.name.mkv']
# ['tv.show.','e02.episode.name.mkv']

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。