私信  •  关注

Samwise

Samwise 最近创建的主题
Samwise 最近回复了
4 年前
回复了 Samwise 创建的主题 » 如何在python中创建inmutable和singleton对象?

可以使用 frozen=True 参数创建数据类 frozen 自动使其可散列,因此您只需使用 functools.cache 而不是实现自己的缓存:

from dataclasses import dataclass
from functools import cache

@dataclass(frozen=True)
class Data:
    data: str

    @cache
    def __new__(cls, data: str) -> "Data":
        return super().__new__(cls)

x = Data("foo")
y = Data("foo")
assert id(x) == id(y)
4 年前
回复了 Samwise 创建的主题 » 在python中重新排列列表

使用 zip 和 * 接线员:

>>> values = [[100000.0, 36.0, 0.08, 20000.0],
...  [200000.0, 12.0, 0.1, 0.0],
...  [628400.0, 120.0, 0.12, 100000.0],
...  [4637400.0, 240.0, 0.06, 0.0],
...  [42900.0, 90.0, 0.07, 8900.0],
...  [916000.0, 16.0, 0.13, 0.0],
...  [45230.0, 48.0, 0.08, 4300.0],
...  [991360.0, 99.0, 0.08, 0.0],
...  [423000.0, 27.0, 0.09, 47200.0]]
>>> list(zip(*values))
[(100000.0, 200000.0, 628400.0, 4637400.0, 42900.0, 916000.0, 45230.0, 991360.0, 423000.0), (36.0, 12.0, 120.0, 240.0, 90.0, 16.0, 48.0, 99.0, 27.0), (0.08, 0.1, 0.12, 0.06, 0.07, 0.13, 0.08, 0.08, 0.09), (20000.0, 0.0, 100000.0, 0.0, 8900.0, 0.0, 4300.0, 0.0, 47200.0)]

如果让新列表由列表而不是元组组成很重要,那么映射 list 在上面:

>>> list(map(list, zip(*values)))
[[100000.0, 200000.0, 628400.0, 4637400.0, 42900.0, 916000.0, 45230.0, 991360.0, 423000.0], [36.0, 12.0, 120.0, 240.0, 90.0, 16.0, 48.0, 99.0, 27.0], [0.08, 0.1, 0.12, 0.06, 0.07, 0.13, 0.08, 0.08, 0.09], [20000.0, 0.0, 100000.0, 0.0, 8900.0, 0.0, 4300.0, 0.0, 47200.0]]
4 年前
回复了 Samwise 创建的主题 » 将项目从python文件写入字典

如果您试图将这些行转换为实际的Python列表,我建议使用 json 单元(另一个选择是 ast.literal_eval ,因为在本例中,语法恰好相同。)

import json

def read_scores_file(file_path):
    with open(file_path) as f:
        return {
            f"score_set{i}": json.loads(line)
            for i, line in enumerate(f)
        }
5 年前
回复了 Samwise 创建的主题 » 在Python中为类属性键入继承性

你可以通过 M 做一个 Generic 类型,它允许子类(或父类的特定实例)缩小 c .

from typing import Generic, Type, TypeVar


class C:
    @staticmethod
    def c_fun() -> int:
        return 23


class C1(C):
    @staticmethod
    def c1_fun() -> int:
        return 42


_CType = TypeVar('_CType', bound=C)


class M(Generic[_CType]):
    def __init__(self, c: Type[_CType]) -> None:
        self.c = c()


class M1(M[C1]):
    def __init__(self, c: Type[C1]) -> None:
        super().__init__(c=c)

    def m1_fun(self) -> None:
        print(self.c.c1_fun())

    def show_type(self) -> None:
        print(type(self.c))


M1(c=C1).m1_fun()  # Output: 42
M1(c=C1).show_type()  # Output: <class '__main__.C1'>

我认为您所指的bug存在于这个函数中:

def reverse_word(line):
  data = line.read()
  data_1 = data[::-1]
  print(data_1)
  return data_1

你不需要打电话 read() 在…上 line 因为它已经是一根弦了; 读() 对文件对象调用,以便将其转换为字符串。只要做:

def reverse_line(line):
    return line[::-1]

它会让整个线路倒转。

如果你想倒转一行中的单个单词,同时保持它们在同一行中的顺序(例如,将“猫坐在帽子上”改为“eht tac tas no a tah”),那应该是这样的:

def reverse_words(line):
    return ' '.join(word[::-1] for word in line.split())

如果你想颠倒单词的顺序,而不是单词本身(例如,将“猫坐在帽子上”改为“猫坐在帽子上”),那将是:

def reverse_word_order(line):
    return ' '.join(line.split()[::-1])
4 年前
回复了 Samwise 创建的主题 » 有没有更有效/更好的方法用python编写测试用例?

不要为只会使用一次的值创建命名变量,尤其是在名称没有添加任何有用信息的情况下(这适用于一般代码,而不仅仅是测试):

print(are_anagrams("danger", "garden"))
print(are_anagrams("nameless", "salesmen"))
print(are_anagrams("name", "sale"))
print(are_anagrams("n", "sa"))

如果你 assert 而不是仅仅打印期望值;这样,您就不需要查看输出并将其与您期望的结果进行比较,您只需运行测试,如果它没有引发 AssertionError 你知道代码的工作方式与你期望的一样:

assert are_anagrams("danger", "garden")
assert are_anagrams("nameless", "salesmen")
assert not are_anagrams("name", "sale")
assert not are_anagrams("n", "sa")

编写这样的测试序列的另一种方法是创建一个表,然后遍历它,例如:

test_cases = [
    ("danger", "garden", True),
    ("nameless", "salesmen", True),
    ("name", "sale", False),
    ("n", "sa", False),
]

for s1, s2, result in test_cases:
    assert are_anagrams(s1, s2) == result

当测试用例更复杂时,表格技术更有用,因为它可以更容易地直观地组织测试数据,以验证您是否覆盖了所有可能的输入组合;它还提供了动态生成表的可能性。

4 年前
回复了 Samwise 创建的主题 » Python逆向工程——为什么代码会产生这种特殊的结果

答案可能是由于Python版本的不同。Python的现代版本 / 作为浮点除法,即使操作数是整数。Python2相当于 // (整数除法)如果操作数是整数。

如果我修改你的代码使用int除法(这似乎是我的意图,因为它也使用 % 操作员)然后我得到了预期的结果:

>>> def find(j):
...     if(j>1):
...         j=find(j/10)-(j%10)
...         print(j)
...     else:
...         j=0
...     return j
...
>>> find(122)
-1.22
-3.419999999999999
-5.419999999999999
-5.419999999999999
>>> def find(j):
...     if(j>1):
...         j=find(j//10)-(j%10)
...         print(j)
...     else:
...         j=0
...     return j
...
>>> find(122)
-2
-4
-4
5 年前
回复了 Samwise 创建的主题 » Python create函数在调用它的函数中自动创建变量?

返回一个集合,允许您按名称访问值,而无需重新分配它们,例如dict:

def set_variables():
    return {
        'a': 10,
        'b': 200,
    }
def parent_function():
   v = set_variables()
   # do some code with v['a'] or v['b']

或者(我个人对这个用例的偏好)a NamedTuple ,这为您提供了类型检查的好处(以及IDE自动完成,就像您使用顶级命名变量一样):

from typing import NamedTuple

class Vars(NamedTuple):
    a: int
    b: int

def set_variables() -> Vars:
    return Vars(a=10, b=200)

def parent_function():
    v = set_variables()
    # do some code with v.a and v.b
4 年前
回复了 Samwise 创建的主题 » 在python中同时创建多个矫揉造作的函数

将两个不同的值作为元组返回。

>>> def inputfunction() -> tuple[int, list[int]]:
...     return (
...         int(input('"enter var1": ')),
...         [int(n) for n in input('"enter coordinates" (x,y): ').split(",")]
...     )
...
>>> var1, coordinates = inputfunction()
"enter var1": 0
"enter coordinates" (x,y): 0,1
>>> print(var1)
0
>>> print(coordinates)
[0, 1]
4 年前
回复了 Samwise 创建的主题 » 如何在python中从一行编译列表?

使用 split() 将字符串拆分为字符串列表。如果你想把这些弦变成 int s、 打电话 智力 每一个都有。

with open("file.txt") as f:
    list1 = f.readline().split()

print(list1)              # ['22', '21', '20']
print([int(n) for n in list1])  # [22, 21, 20]

我想你想要的是:

import collections

n = [int(input()) for _ in range(5)]
p = collections.Counter(n)
for i, freq in p.items():
    print(f"{i}: {freq / len(n)}")

参数为 collections.Counter 应该是你的清单;然后你可以迭代 Counter 作为dict,其中键是列表中的项目(用户输入的数字),值是每个项目出现的次数。将计数除以列表的总长度可以告诉您每个项目出现的时间百分比。

1
2
3
2
2
1: 0.2
2: 0.6
3: 0.2

如果你只想得到一个出现频率最高的数字,可以选择 max 这样地:

print(f"Most frequent: {max(p, key=p.get)}")

sys.argv 是传递给的所有参数的列表 python (以脚本的名称开头)。您只需像其他列表一样遍历其中的每个元素:

import sys

for variable in sys.argv[1:]:
    with open(f"{variable}.txt", "w") as w_file:
        w_file.write("Something")

注意 sys.argv[0] 将 code.py ,您可能不想覆盖它。

4 年前
回复了 Samwise 创建的主题 » 在python中,中断内部循环并将控制传递给最外层的循环

一种方法是使用 else: 块以捕获内部循环未中断的情况(在这种情况下,您希望 continue ),然后是 break 如果 else 还没有继续:

coords = []
with open('ADM2_hits.csv') as csvFile:
    csvReader = csv.reader(csvFile)
    next(csvReader)
    for line in csvReader:
        keyword = line[1]
        for dic in adm2_geonames:
            for x in dic["geonames"]:
                if(keyword == x['name']):
                    line.append(x['lat'])
                    line.append(x['lng'])
                    coords.append(line)
                    break
            else:
                continue
            break
print(coords)

请注意,只需直接转到 dic["geonames"] 而不是在整本字典上循环;字典的全部意义在于,你可以通过它的键直接跳转到一个给定的条目,而不必反复搜索整个条目。

createmultiplier(10) 创建一个将其参数乘以10的函数。就是这样 multiply 分配给…因此 multiply(15) 返回 150 .

换句话说:

multiply = createmultiplier(10)

具有与执行以下操作相同的效果:

def multiply(y)
    return 10 * y

函数的点,如 createmultiplier 就是让你在没有 def 陈述 和 无需硬编码实现细节,如常量 10 .例如,如果你想让所有数字的倍数从1到4,你可以:

def times_1(y):
    return 1 * y

def times_2(y):
    return 2 * y

def times_3(y):
    return 3 * y

def times_4(y):
    return 4 * y

multipliers = [times_1, times_2, times_3, times_4]
print([m(10) for m in multipliers])  # [10, 20, 30, 40]

但这要容易得多:

def create_multiplier(x):
    return lambda y: y*x

multipliers = [create_multiplier(x) for x in range(1, 5)]
print([m(10) for m in multipliers])  # [10, 20, 30, 40]
4 年前
回复了 Samwise 创建的主题 » 如何在Python中读取列表项中的元素?

鉴于 output 作为 Annotation 物体:

output = [Annotation(...)]

你应该能够简单地做到:

shp = output[0].shape
lbl = output[0].labels
dmn = labels[0].domain
4 年前
回复了 Samwise 创建的主题 » 在python中实现的虚拟函数没有任何初始化

与其将其视为“虚拟函数”,不如将其视为“duck类型”的一个示例。在这个表达中:

self.print_hello()

我们只需访问 print_hello 属性 self (不管是什么),然后叫它。如果没有这样的属性,则 AttributeError 在运行时引发。如果属性不可调用,则 TypeError 她长大了。这就是全部。没有对这类问题做出任何假设 自己 --我们只是让它“像鸭子一样呱呱叫”,看看它能不能。

duck类型的危险在于,如果你实例化一个 parent_print 打电话 print_word 在这方面,它将失败:

abstract_print = parent_print()
abstract_print.print_word()
# raises AttributeError: 'parent_print' object has no attribute 'print_hello'

Python确实支持静态类型声明和抽象类的概念,这可以帮助您避免错误。例如,如果我们运行静态类型检查器( mypy )在您的代码中,我们将得到一个错误:

test.py:4: error: "parent_print" has no attribute "print_hello"

这是完全正确的——从静态类型的角度来看,调用 打印你好 因为我们还没有确定这一切 家长打印 实例具有这样的属性。

为了解决这个问题,我们可以宣布 打印你好 作为一种抽象方法(为了培养良好习惯,我还将清理名称以匹配标准Python约定):

from abc import ABC, abstractmethod

class ParentPrint(ABC):
    
    @abstractmethod
    def print_hello(self) -> None: ...

    def print_word(self) -> None:
        self.print_hello()
        
class ChildPrint(ParentPrint):
    
    def print_hello(self) -> None:
        print('Hello')
        
        
basic_print = ChildPrint()
basic_print.print_word()

现在代码类型检查没有问题。

这个 @abstractmethod decorator还指出该类是抽象的(“纯虚拟的”),无法实例化。如果我们试图创造一个 ParentPrint 或 任何 它的子类没有提供抽象方法的实现,我们得到一个错误, 二者都 静态地从 麦皮 在运行时以 打字错误 在您尝试实例化对象时(甚至在您尝试调用抽象方法之前),会立即引发该问题:

abstract_print = ParentPrint()
# raises error: Cannot instantiate abstract class "ParentPrint" with abstract attribute "print_hello"
4 年前
回复了 Samwise 创建的主题 » Python对列表中的所有对象运行函数
class MyClass():
    list3 = []

list3 是一个类变量,因此该类的所有实例都共享它。每次添加到 清单3 在…上 任何 例如,它是附加到单一共享列表的。

修理 MyClass 使 清单3 实例变量将为您提供所需的行为:

class MyClass:
    def __init__(self):
        self.list3 = []

我还建议简化你的工作 for 循环,因为它们有点难以遵循;如果按元素进行迭代,就更容易弄清楚每个循环在做什么。(此外,避免使用内置名称调用变量,如 list !)

list1 = [[MyClass(), MyClass()], [MyClass()]]
list2 = [2, 2]

for sublist, num in zip(list1, list2):
    for obj in sublist:
        obj.list3.extend(1 for _ in range(num))

for sublist in list1:
    for obj in sublist:
        print(obj.list3)

印刷品:

[1, 1]
[1, 1]
[1, 1]