跳至内容
Py_tricks

Py_tricks

.pop(self,index)方法

1
2
3
a=[1,2,3]
a.pop(1)
print(a)	# [1,3]

函数传实参还是形参问题

在 Python 中,参数传递始终是 引用传递(传地址的)。但根据对象类型(可变/不可变)的不同,会产生类似「值传递」或「引用传递」的表象:

结论:看对象类型

  1. 不可变对象(字符串、数字、元组等)作为参数时:
    • 形参接收到的是对象的引用
    • 若在函数内修改形参,会创建新对象,实参不受影响(类似值传递)
    • nonlocal声明实现访问外部变量?
  2. 可变对象(列表、字典、集合等)作为参数时:
    • 形参接收到的也是对象的引用
    • 若在函数内 原地修改 形参(如 append、+= 等操作),实参会同步变化(类似引用传递)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
def f(obj):
    # 修改形参
    obj += obj  
    
# 不可变对象(字符串)
obj1 = "123456"    
demo(obj1)
print("函数调用后obj1:" + obj1)  # 123456(未变)

# 可变对象(列表)
obj2 = [1,2,3]     
demo(obj2)          
print("函数调用后obj2:" + str(obj2))  # [1,2,3,1,2,3](已变)

pychram 来回查看代码

pycharm会用ctrl+鼠标左键点击函数来进入函数体查看函数具体实现部分。但是我常常点击后就回不来了,不同文件的函数调用来回找让人头大。

可以来回的方法是:

  • ctrl+alt+左方向键(←) 后退(回退回原来位置, 不行就多摁几次,因为光标点击的地方好像也会记录)

  • ctrl+alt+右方向键(→) 前进(即回到刚才点击的函数位置)

参考链接:https://blog.csdn.net/shmily_ke/article/details/136975710

for _ in range(len(queue))

下划线 ‘_’:_ 是一个占位符,表示“我不关心这个索引值”

len(queue)忽略循环中queue本身的变化

特性for _ in range(len(queue))for _ in queue
遍历方式基于索引,范围固定动态跟踪变化
q 增加元素不会遍历到新添加的元素可能会遍历到新添加的元素
**q 删除元素 **可能导致索引越界可能导致跳过元素或提前结束

103. 二叉树的锯齿形层序遍历 - 力扣(LeetCode)

对比我的代码和题解代码如下:

我的还要用cnt记录下一层的结点个数,它只需要for _ in range(len(queue))中的len(queue)就能保留一层的值然后循环。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
class Solution:
    def zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if not root: return []
        res, queue = [], collections.deque()
        queue.append(root)
        while queue:
            tmp = []
            for _ in range(len(queue)):
                node = queue.popleft()
                tmp.append(node.val)
                if node.left: queue.append(node.left)
                if node.right: queue.append(node.right)
            res.append(tmp[::-1] if len(res) % 2 else tmp)
        return res

链接:https://leetcode.cn/problems/binary-tree-zigzag-level-order-traversal/solutions/2361613/103-er-cha-shu-de-ju-chi-xing-ceng-xu-bi-qz2q/

部分 可迭代型数据 逆序

  • list.reverse()
  • reversed(iterable)
  • list[::-1]——需要对象有__getitem__,最好用
特性reverse()reversed()[::-1]
‌功能‌原地反转列表返回反转后的迭代器返回反转后的新对象
‌适用对象‌仅列表(list)所有可迭代对象(列表、元组、字符串等)所有支持切片的有序序列(列表、字符串、元组等)
‌返回值‌None迭代器反转后的新对象
‌内存效率‌高(原地操作,不生成新对象)高(返回迭代器,不生成完整副本)低(生成完整副本,占用额外内存)
‌时间复杂度‌O(n)(直接交换元素)O(1)(延迟计算,实际遍历时 O(n))O(n)(复制所有元素)
‌修改原数据‌✅ 是❌ 否❌ 否
‌支持链式操作‌❌ 否(返回 None)✅ 是(可与 list()、join() 等结合)✅ 是(直接生成新对象)

for key in dic_1 if key in dic_2

1
2
3
4
5
6
dic_1={'a':1,'b':2,'c':3}
dic_2={'b':2}
dic_3 = {
    key: dic_1[key] for key in dic_1 if key in dic_2
}
print(dic_3)	# {'b': 2}

声明多个全局变量

逗号 隔开,“ \ ”连接下一行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
global \
    _manager, \
    is_multiprocess, \
    _storage_lock, \
    _internal_lock, \
    _pipeline_status_lock, \
    _shared_dicts, \
    _init_flags, \
    _initialized, \
    _update_flags

字典

.join方法

1
2
3
4
5
content = "数据1|数据2#数据3@需要保留的+符号+数据4"
markers = ["|", "#", "@", "+"]

results = re.split("|".join(re.escape(marker) for marker in markers), content)
print(results)

dataclasses

dataclasses 的 dataclass, field

pycharm书签功能

按 F11 对光标那行生成书签

pycharm关警告

  1. 右上角有 黄色三角形警告图标⚠
  2. 直接鼠标放置⚠处
  3. 会自动显示 如 “ 25个警告,3个弱警告 高亮显示:所有问题 ”
  4. 点击 高亮显示:所有问题
  5. 弹出“无 语法 所有问题”,点击 无 即可。

func(*args,**kwargs)

函数定义中,可以有一个 *args 和 一个 **kwargs 参数,args 和 kwargs 是约定俗成的参数命名。也就是说可以func(*a,**b)

我的理解:

  • args是一个元组,*args是解包,即 未知元组(a,b…) 解包成 a,b… 放到func的括号里,变成 func(a,b…)
  • kwargs是一个字典未知字典{a: b, c: d…},解包放func里,变成 func(a=b, c=d…)

使用式理解:

*func(fixed_arg, args, obvious_kwarg=123, **kwargs)中

  1. fixed_arg 传递:它是固定位置参数,没有默认值。
  2. *args 接收所有多余的位置参数:所有未被 fixed_arg 接收的位置参数都会被打包到 *args。
  3. obvious_kwarg 是仅限关键字参数:它只能通过关键字传递,不能通过位置传递。
  4. **kwargs 接收所有多余的关键字参数:所有未被 fixed_arg、*args 和 obvious 接收的关键字参数都会被打包到 **kwargs。
1
2
3
4
5
6
7
def func(fixed_arg, *args, obvious_kwarg=123, **kwargs):
    print(f"位置参数: {fixed_arg}")		 # 10
    print(f"多余的位置参数: {args}")	   # (20, 30)
    print(f"显式传递的关键字参数: {obvious_kwarg}")	# 60
    print(f"可变关键字参数: {kwargs}")	   # {'x': 40, 'y': 50}

func(10, 20, 30, x=40, y=50, obvious_kwarg=60)

[a:b]不包含第b个元素

[a:b]不包含第b个元素,没了

题目:填空,s是个str,长度>1,获取其前缀,如"123 -> 1 12 123"

s_arr=[s[ __ ] for i in range( ___ )]

1
2
3
4
s="123"
# :i 表示 0:i,不包含元素[i],所以若要包括元素[len(s)-1],i 范围为 1~len(s),range要产生1~len(s),则range(1,len(s)+1)
s_arr=[s[:i] for i in range(1, len(s)+1)]
print(s_arr)

from collections import defaultdict

直译 —— 有默认的 值 的字典

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from collections import defaultdict
maybe_nodes = defaultdict(list)

# 访问不存在的键 "A",会自动创建一个空列表
maybe_nodes["A"].append(1)
maybe_nodes["A"].append(2)

# 访问不存在的键 "B",同样会自动创建一个空列表
maybe_nodes["B"].append(3)

print(maybe_nodes) # defaultdict(<class 'list'>, {'A': [1, 2], 'B': [3]})

.extend

对比.extend和.append

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
base_list = [1, 2, 3]
to_add = [4, 5]

# 使用 append
base_list.append(to_add)
print(base_list)  # 输出 [1, 2, 3, [4, 5]] → 整个列表被当作一个元素添加

# 使用 extend
base_list = [1, 2, 3]
base_list.extend(to_add)
print(base_list)  # 输出 [1, 2, 3, 4, 5] → 逐个元素合并

pycharm折叠、展开

折叠所有代码 Ctrl Shift -

展开所有代码 Ctrl Shift +

折叠光标所在层所有可折叠代码(truncate) Ctrl Alt -

展开光标所在层所有可折叠代码(truncate) Ctrl Alt +

折叠光标所在层 Ctrl -

开光标所在层 Ctrl +

提示词工程代码例子

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
async def _handle_entity_relation_summary(
    entity_or_relation_name: str,
    description: str,
    global_config: dict,
) -> str:
    use_llm_func: callable = global_config["llm_model_func"]
    llm_max_tokens = global_config["llm_model_max_token_size"]
    tiktoken_model_name = global_config["tiktoken_model_name"]
    summary_max_tokens = global_config["entity_summary_to_max_tokens"]
    language = global_config["addon_params"].get(
        "language", PROMPTS["DEFAULT_LANGUAGE"]
    )

    # description=dsri_1<SEP>dsri_2<SEP>...
    # 获取描述的tokens并判断是否要总结
    tokens = encode_string_by_tiktoken(description, model_name=tiktoken_model_name)
    if len(tokens) < summary_max_tokens:  # No need for summary
        return description
    # 将多个dsri 总结成一个综合的
    prompt_template = PROMPTS["summarize_entity_descriptions"]
    # 保证在llm最大tokens限制下
    use_description = decode_tokens_by_tiktoken(
        tokens[:llm_max_tokens], model_name=tiktoken_model_name
    )
    # description_list: dsri_1<SEP>dsri_2<SEP> 被<SEP>分割
    context_base = dict(
        entity_name=entity_or_relation_name,
        description_list=use_description.split(GRAPH_FIELD_SEP),
        language=language,
    )
    use_prompt = prompt_template.format(**context_base)
    logger.debug(f"Trigger summary: {entity_or_relation_name}")
    summary = await use_llm_func(use_prompt, max_tokens=summary_max_tokens)
    return summary

pycharm一直显示正在关闭项目

pycharm关闭后一直显示正在关闭项目的解决方法-CSDN博客

生成当前环境配置的txt

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# deepseek-r1生成后删减得来
import sys
import platform
import subprocess
from importlib.metadata import distributions

def get_environment_info():
    env_info = {
        # 系统信息
        "操作系统": f"{platform.system()} {platform.release()} {platform.version()}",
        "系统架构": platform.architecture()[0],
        "主机名": platform.node(),

        # Python环境
        "Python版本": sys.version.replace('\n', ' '),
        "虚拟环境": "是" if hasattr(sys, 'real_prefix') or sys.prefix != sys.base_prefix else "否",

        # 包管理信息
        "已安装包": [f"{dist.metadata['Name']}=={dist.version}" for dist in distributions()],

    }

    # 获取conda信息(如果可用)
    try:
        result = subprocess.run(['conda', 'list'], capture_output=True, text=True, check=True)
        env_info["Conda包列表"] = result.stdout.splitlines()
    except:
        env_info["Conda包列表"] = 'conda list fail'
        pass

    return env_info


if __name__ == "__main__":
    info = get_environment_info()

    # 打印摘要信息
    print("=" * 50 + "\n环境配置摘要:\n" + "=" * 50)
    print(f"操作系统: {info['操作系统']}")
    print(f"Python版本: {info['Python版本'].split(' [')[0]}")
    print(f"虚拟环境: {info['虚拟环境']}")
    print(f"已安装包数量: {len(info['已安装包'])}")

    # 保存完整信息到文件
    with open("environment_report.txt", "w", encoding="utf-8") as f:
        for key, value in info.items():
            f.write(f"\n=== {key} ===\n")
            if isinstance(value, list):
                f.write('\n'.join(value))
            elif isinstance(value, dict):
                for k, v in value.items():
                    f.write(f"{k}: {v}\n")
            else:
                f.write(str(value))

    print("\n完整环境报告已保存到 environment_report.txt")

@cache

377. 组合总和 Ⅳ - 力扣(LeetCode)

problem: 试图在类方法 combinationSum4 前加@cache,报错。

explanation:@cache 试图将 combinationSum4 的所有参数 (self, nums, target) 打包成一个元组 (self_object, [1,2,3], 4) 来作为缓存字典的key,但是list不可哈希。

solution:将 @cache 应用在参数简单且可哈希的递归辅助函数上。

1
2
3
4
5
6
class Solution:
    def combinationSum4(self, nums: List[int], target: int) -> int:
        @cache  # <--- 装饰的是 dfs
        def dfs(i: int) -> int: # dfs 的参数 i 是一个整数
            # ...
        return dfs(target)
最后更新于