python 格式化字符、列表推导式

发布时间:2024年01月20日

1. 格式化字符串f-string

  • f-string,亦称为格式化字符串常量, f-string在形式上是以 f F 修饰符引领的字符串(f'xxx' F'xxx'),以大括号{}标明被替换的字段;
  • f-string在功能方面不逊于传统的%-formatting语句和str.format()函数,同时性能又优于二者,且使用起来也更加简洁明了,

1. 1 简单使用

>>> name = 'Eric'
>>> f'Hello, my name is {name}'
'Hello, my name is Eric'

>>> number = 7
>>> f'My lucky number is {number}'
'My lucky number is 7'

1.2 表达式求值与函数调用

>>> f'A total number of {24 * 8 + 4}'
'A total number of 196'

>>> f'Complex number {(2 + 2j) / (2 - 3j)}'
'Complex number (-0.15384615384615388+0.7692307692307692j)'

>>> name = 'ERIC'
>>> f'My name is {name.lower()}'
'My name is eric'

>>> import math
>>> f'The answer is {math.log(math.pi)}'
'The answer is 1.1447298858494002'

1.3 多行f-string

  • 案例1

f-string还可用于多行字符串

name = 'Eric'
age = 27
f"Hello!" \
f"I'm {name}." \
f"I'm {age}."
"Hello!I'm Eric.I'm 27."


f"""Hello!
I'm {name}.
I'm {age}."""
  • 案例2
 LOGGER.info(
        f"\n{'OS':<20}{platform.platform()}\n"
        f"{'Environment':<20}{ENVIRONMENT}\n"
        f"{'Python':<20}{sys.version.split()[0]}\n"
        f"{'Install':<20}{'git' if is_git_dir() else 'pip' if is_pip_package() else 'other'}\n"
        f"{'RAM':<20}{ram_info:.2f} GB\n"
        f"{'CPU':<20}{get_cpu_info()}\n"
        f"{'CUDA':<20}{torch.version.cuda if torch and torch.cuda.is_available() else None}\n"
    )

 if is_github_action_running():
        LOGGER.info(
            f"\nRUNNER_OS: {os.getenv('RUNNER_OS')}\n"
            f"GITHUB_EVENT_NAME: {os.getenv('GITHUB_EVENT_NAME')}\n"
            f"GITHUB_WORKFLOW: {os.getenv('GITHUB_WORKFLOW')}\n"
            f"GITHUB_ACTOR: {os.getenv('GITHUB_ACTOR')}\n"
            f"GITHUB_REPOSITORY: {os.getenv('GITHUB_REPOSITORY')}\n"
            f"GITHUB_REPOSITORY_OWNER: {os.getenv('GITHUB_REPOSITORY_OWNER')}\n"
        )
  • 案例3
raise ValueError(
             f"Invalid CUDA 'device={device}' requested."
             f" Use 'device=cpu' or pass valid CUDA device(s) if available,"
             f" i.e. 'device=0' or 'device=0,1,2,3' for Multi-GPU.\n"
             f"\ntorch.cuda.is_available(): {torch.cuda.is_available()}"
             f"\ntorch.cuda.device_count(): {torch.cuda.device_count()}"
             f"\nos.environ['CUDA_VISIBLE_DEVICES']: {visible}\n"
             f"{install}"
         )
  • 案例4
GITHUB_ASSETS_REPO = "ultralytics/assets"
GITHUB_ASSETS_NAMES = (
    [f"yolov8{k}{suffix}.pt" for k in "nsmlx" for suffix in ("", "-cls", "-seg", "-pose", "-obb")]
    + [f"yolov5{k}{resolution}u.pt" for k in "nsmlx" for resolution in ("", "6")]
    + [f"yolov3{k}u.pt" for k in ("", "-spp", "-tiny")]
    + [f"yolo_nas_{k}.pt" for k in "sml"]
    + [f"sam_{k}.pt" for k in "bl"]
    + [f"FastSAM-{k}.pt" for k in "sx"]
    + [f"rtdetr-{k}.pt" for k in "lx"]
    + ["mobile_sam.pt"]
)
GITHUB_ASSETS_STEMS = [Path(k).stem for k in GITHUB_ASSETS_NAMES]
  • 案例5
 LOGGER.info(
            f'Image sizes {self.args.imgsz} train, {self.args.imgsz} val\n'
            f'Using {self.train_loader.num_workers * (world_size or 1)} dataloader workers\n'
            f"Logging results to {colorstr('bold', self.save_dir)}\n"
            f'Starting training for '
            f'{self.args.time} hours...'
            if self.args.time
            else f"{self.epochs} epochs..."
        )
  • 案例6
content = f"""
# Ultralytics Multi-GPU training temp file (should be automatically deleted after use)
overrides = {vars(trainer.args)}

if __name__ == "__main__":
    from {module} import {name}
    from ultralytics.utils import DEFAULT_CFG_DICT

    cfg = DEFAULT_CFG_DICT.copy()
    cfg.update(save_dir='')   # handle the extra key 'save_dir'
    trainer = {name}(cfg=cfg, overrides=overrides)
    results = trainer.train()
"""

1.4 对齐格式

在这里插入图片描述

  • 案例1
if verbose:
     LOGGER.info(f"\n{'':>3}{'from':>20}{'n':>3}{'params':>10}  {'module':<45}{'arguments':<30}")
  • 案例2
if s:
   if install and AUTOINSTALL:  # check environment variable
       n = len(pkgs)  # number of packages updates
       LOGGER.info(f"{prefix} Ultralytics requirement{'s' * (n > 1)} {pkgs} not found, attempting AutoUpdate...")
       try:
           t = time.time()
           assert is_online(), "AutoUpdate skipped (offline)"
           LOGGER.info(subprocess.check_output(f"pip install --no-cache {s} {cmds}", shell=True).decode())
           dt = time.time() - t
           LOGGER.info(
               f"{prefix} AutoUpdate success ? {dt:.1f}s, installed {n} package{'s' * (n > 1)}: {pkgs}\n"
               f"{prefix} ?? {colorstr('bold', 'Restart runtime or rerun command for updates to take effect')}\n"
           )
       except Exception as e:
           LOGGER.warning(f"{prefix} ? {e}")
           return False
   else:
       return False
  • 案例3
  if detailed:
        LOGGER.info(
            f"{'layer':>5} {'name':>40} {'gradient':>9} {'parameters':>12} {'shape':>20} {'mu':>10} {'sigma':>10}"
        )
        for i, (name, p) in enumerate(model.named_parameters()):
            name = name.replace("module_list.", "")
            LOGGER.info(
                "%5g %40s %9s %12g %20s %10.3g %10.3g %10s"
                % (i, name, p.requires_grad, p.numel(), list(p.shape), p.mean(), p.std(), p.dtype)
            )

  • 案例4
  LOGGER.info(
        f"{'Params':>12s}{'GFLOPs':>12s}{'GPU_mem (GB)':>14s}{'forward (ms)':>14s}{'backward (ms)':>14s}"
        f"{'input':>24s}{'output':>24s}"
    )
assert x.shape[-1] == 4, f"input shape last dimension expected 4 but input shape is {x.shape}"

1.5 宽度与精度描述符

在这里插入图片描述

  • 注1:0width 不可用于复数类型和非数值类型,width.precision 不可用于整数类型
  • 注2:width.precision 用于不同格式类型的浮点数、复数时的含义也不同:用于 f、F、e、E % 时 precision 指定的是小数点后的位数,用于 gGprecision 指定的是有效数字位数(小数点前位数+小数点后位数)。
  • 注3:width.precision 除浮点数、复数外还可用于字符串,此时 precision 含义是只使用字符串中前 precision 位字符。
>>> a = 123.456
>>> f'a is {a:8.2f}'
'a is   123.46'
>>> f'a is {a:08.2f}'
'a is 00123.46'
>>> f'a is {a:8.2e}'
'a is 1.23e+02'
>>> f'a is {a:8.2%}'
'a is 12345.60%'
>>> f'a is {a:8.2g}'
'a is  1.2e+02'

>>> s = 'hello'
>>> f's is {s:8s}'
's is hello   '
>>> f's is {s:8.3s}'
's is hel     '
cv2.rectangle(self.im0, (15, 25), (280, 70), (255, 255, 255), -1)
cv2.putText(
   self.im0, f"Distance : {distance:.2f}m", (20, 55), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 0), 2, cv2.LINE_AA
     )
if m == self.model[0]:
	LOGGER.info(f"{'time (ms)':>10s} {'GFLOPs':>10s} {'params':>10s}  module")
	LOGGER.info(f"{dt[-1]:10.2f} {flops:10.2f} {m.np:10.0f}  {m.type}")
if c:
    LOGGER.info(f"{sum(dt):10.2f} {'-':>10s} {'-':>10s}  Total")

2. 列表表达式

2.1 列表推导式的2种形式

  • if语句在for语句后
[exp for x in data if condition]
  • if语句在for语句前
[exp1 if condition else exp2 for x in data]

这两种本质上没有任何区别,个人推荐用第一种: if语句在for语句后, 很多项目的写法都是采用这种方式

2.2 单个for循环

语法
[ expr1(x) for x in iter_data1 if command1 else expr2(x) if command2 else expr3(x)  ]
案例
  • 案例1
  [value for x in input if isinstance(input, list) else [input]]
  • 案例2
 x["train_args"] = {k: v for k, v in args.items() if k in DEFAULT_CFG_KEYS}
  • 案例3
freeze_list = (
     self.args.freeze
     if isinstance(self.args.freeze, list)
     else range(self.args.freeze)
     if isinstance(self.args.freeze, int)
     else []
 )
  • 案例4
gs = max(int(self.model.stride.max() if hasattr(self.model, "stride") else 32), 32)
  • 案例5
LOGGER.info(colorstr(s) + ", ".join(f"{k}={strip_auth(v)}" for k, v in args.items()))
  • 案例6
class Conv(nn.Module):
    """Standard convolution with args(ch_in, ch_out, kernel, stride, padding, groups, dilation, activation)."""

    default_act = nn.SiLU()  # default activation

    def __init__(self, c1, c2, k=1, s=1, p=None, g=1, d=1, act=True):
        """Initialize Conv layer with given arguments including activation."""
        super().__init__()
        self.conv = nn.Conv2d(c1, c2, k, s, autopad(k, p, d), groups=g, dilation=d, bias=False)
        self.bn = nn.BatchNorm2d(c2)
        self.act = self.default_act if act is True else act if isinstance(act, nn.Module) else nn.Identity()

2.3 双重for循环

语法
  • 简单的多重for循环
[ expr1(x1,x2) for x1 in iter_data1 for x2 in iter_data2]
  • 多重for循环+ if else
[exp1 if con1 else exp2 if con1 else exp3 for data1 in iter_data1 for data2 in iter_data2]
案例
  • 案例1
  [f"yolov8{k}{suffix}.pt" for k in "nsmlx" for suffix in ("", "-cls", "-seg", "-pose", "-obb")]
GITHUB_ASSETS_REPO = "ultralytics/assets"
GITHUB_ASSETS_NAMES = (
    [f"yolov8{k}{suffix}.pt" for k in "nsmlx" for suffix in ("", "-cls", "-seg", "-pose", "-obb")]
    + [f"yolov5{k}{resolution}u.pt" for k in "nsmlx" for resolution in ("", "6")]
    + [f"yolov3{k}u.pt" for k in ("", "-spp", "-tiny")]
    + [f"yolo_nas_{k}.pt" for k in "sml"]
    + [f"sam_{k}.pt" for k in "bl"]
    + [f"FastSAM-{k}.pt" for k in "sx"]
    + [f"rtdetr-{k}.pt" for k in "lx"]
    + ["mobile_sam.pt"]
)
  • 案例2
list_x = [10,1]
list_y = [1,8]
 
print([x if x>y else y if y>x else 'eq' for x in list_x for y in list_y])
 
# [10, 10, 'eq', 8]

一般来说多层if else语句放在一边,for语句放在另一边,尽可能别交叉放置,极可能出现错误

参考

代码参考:https://github.com/ultralytics/ultralytics

文章来源:https://blog.csdn.net/weixin_38346042/article/details/135685069
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。