使用数据类遍历列表,并检查元素是否与输入的 int 匹配?

Iterating through a list with dataclasses, and checking if an element matches the inputted int?

提问人:regexted 提问时间:12/16/2022 最后编辑:regexted 更新时间:12/16/2022 访问量:181

问:

我的代码遇到了一些问题。我正在尝试从列表中获取 ID 并将其与 int 输入进行比较。如果 int 与 ID 相同,则会打印(“Yes”)。如果它与 ID 不匹配,它将打印(“no”)。问题是,它甚至为应该返回“是”的数字打印“否”。

from dataclasses import dataclass


@dataclass
class Dog:
    ID: int
    name: str


dog_details = [
    Dog(
        ID=1,
        name="Toby"),
    Dog(
        ID=2,
        name="Rex",
    ),
    Dog(
        ID=3,
        name="Sandy",
    ),
    Dog(
        ID=4,
        name="Wanda",
    ),
    Dog(
        ID=5,
        name="Toto",
    ),
]

while True:
    for index in range(len(dog_details)):
        identification = int(input("What ID? "))
        if identification != dog_details:
            print("no")
        elif identification == dog_details:
            print("Yes")

我正在玩弄以下变体:



while True:
    for index in range(len(dog_details)):

        identification = int(input("What ID? "))
        if identification != dog_details:
            print("no")
        elif identification == dog_details:
            print("Yes")

问题是,它对输入的每个数字都说不。

Python 列表 循环 嵌套列表 python-dataclasses

评论

0赞 Paul Collingwood 12/16/2022
print(dog_details) 与标识相比时,print(identification) 也 .它们是一样的吗?
0赞 regexted 12/16/2022
dog_details :[Dog(ID=1, name='Toby'), Dog(ID=2, name='Rex'), Dog(ID=3, name='Sandy'), Dog(ID=45, name='Wan'), Dog(ID=450, name='To')] 标识 : 2
0赞 Axe319 12/16/2022
您知道如何访问对象的属性吗?
0赞 Paul Collingwood 12/16/2022
“[Dog(ID=1, name='Toby')”等于“1”吗?
0赞 regexted 12/16/2022
@Axe319对不起,我打错了。编辑!

答:

1赞 Samwise 12/16/2022 #1

dog_details是 s 的列表;它永远不会等于 .Dogint

我想你可能想要的是:

while True:
    for dog in dog_details:
        identification = int(input("What ID? "))
        if identification == dog.ID:
            print(f"Yes, this is {dog.name}")
        else:
            print(f"no, this is {dog}")

请注意,由于您在循环中请求 ID,因此您将该 ID 与列表中的特定 ID 进行比较。(我把它添加到声明中,这样当它说“不”时,你可以看到它正在将你的ID与哪只狗进行比较。如果您想将它与所有狗进行比较并返回匹配的狗,请执行:fordogdogprint

dogs_by_id = {dog.ID: dog for dog in dog_details}
while True:
    identification = int(input("What ID? "))
    if identification in dogs_by_id:
        print(f"Yes: {dogs_by_id[identification].name}")
    else:
        print("no")

第一行创建一个允许您通过其 ID 查找狗。如果你在没有字典的情况下做到这一点,那就更复杂了;每次都需要遍历整个列表,如下所示:dict

while True:
    identification = int(input("What ID? "))
    for dog in dog_details:
        if dog.ID == identification:
            print(f"Yes: {dog.name}")
            break
    else:
        print("no")

评论

0赞 regexted 12/16/2022
第二个似乎已经成功了。这是我第一次使用数据类,所以列表格式让我感到困惑。谢谢!!
1赞 J_H 12/16/2022 #2

您想将 ID 与标识进行比较。

identification = 0
while identification >= 0:
    identification = int(input("What ID? "))
    found_dog = None

    for dog in dog_details:
        if dog.ID == identification:
            found_dog = dog

    if found_dog:
        print("Yes!", found_dog)
    else:
        print("No.")

键入 -1 或 CTRL-C 退出循环。

评论

0赞 STerliakov 12/16/2022
for... if... found=something在 Python 中通常是一种反模式,除非你有很长或很复杂的条件。它可以在没有默认的情况下减少到甚至周围。found_dog = next((dog for dog in dog_details if dog.ID == identification), None)try/except/elsenext
2赞 J_H 12/16/2022
我试着在我找到他们的地方见到他们。OP 是 ATM 仍在为索引与迭代而苦苦挣扎,所以我希望在他们未来的写作中鼓励使用简单的成语。多行格式鼓励 print() / breakpoint() 调试。我考虑过提前退出,所以 O(N) 搜索速度提高了 2 倍,但仍然是 O(N) 线性的,并选择拒绝这种复杂性,因为它不适合教学。这里的 dict / set 解决方案很可爱,支持重复 O(1) 查找;我只是没有去那里。我觉得它们是非常好的解决方案。for x in xs:break
0赞 STerliakov 12/16/2022
嗯,真的有道理,太好了!我没有从那个角度看
0赞 irahorecka 12/16/2022 #3

您必须使用类的属性来访问 Dog 实例的 ID();然后,您可以检查相等性,并且您的程序应按预期运行。IDDogint

from dataclasses import dataclass


@dataclass
class Dog:
    ID: int
    name: str

dog_details = [
    Dog(ID=1, name="Toby"),
    Dog(ID=2, name="Rex"),
    Dog(ID=3, name="Sandy"),
    Dog(ID=4, name="Wanda"),
    Dog(ID=5, name="Toto"),
]

dog_ids = set(d.ID for d in dog_details)
while True:
    id_ = int(input("What ID? "))
    if id_ not in dog_ids:
        print('no')
    else:
        print('yes')
        break