【问题标题】:What could be a better alternative to this For?有什么比这个 For 更好的选择?
【发布时间】:2021-07-29 18:49:47
【问题描述】:

我是一名初学者,正在尝试编写一个关于 Python 3.x 交易的游戏。

我有两个班级(Depot 和 Good)。 Good 类的实例存储在 depot.inv 内的字典中(实例为 Key,其数量为 Value)。当用户被要求写下他想拿什么时,他会写下实例的名称('Iron' 而不是 ir)。因此,我使用了一个 For 循环并搜索了 Depot 库存中的所有内容。如果他发现用户对任何实例的名称(例如ir.name)的回复是=,那么程序就可以访问整个实例。

问题是,如果没有 For-Loop,我怎么能做到这一点?

我认为每次做出回复时搜索整个库存并不是最佳的,如果是线性搜索则更不用说。

class Depot:
    def __init__ (self, name, inv, bank):
      self.name = name
      self.inv = inv
      self.bank = bank

class Good:
    def __init__(self, name, weight, rare):
      self.name = name
      self.weight = weight
      self.rare = rare

ir = Good('Iron', 1, 0.1)
gd = Good('Gold', 0.4, 2)
sl = Good('Silver', 0.7, 6.3)
mars = Depot('Mars', {ir: 10500, gd: 800, sl: 6000}, 1000)
player = {ir: 100}

reply = input('What do you want to take?')

i, q = reply.split()

for k in mars.inv.keys():    #This is the crux of the problem
  if i in k.name:
    x = k
    print('Got it')

if x in mars.inv:
  if int(q) > mars.inv[x]:
    print('We dont have that much.')
  elif int(q) <= mars.inv[x]:
    mars.inv[x] -= int(q)
    if x in player:
      player[x] += int(q)
    elif i not in player:
      player[x] = int(q)

【问题讨论】:

  • 这是在对象内部存储名称之类的问题,这可能是查找的关键。它有一些重复,但是将您的库存更改为更像{"Iron": (ir, 10500), "Gold": (gd, 800), "Silver": (sl, 6000} 将允许直接按名称查找。您还可以将 Good 类的名称设为可散列/相等,因此它在查找过程中就像其名称一样,但这有点 hacky。
  • 你也可以有多个字典。一个字典映射名称-> 对象。另一个映射名称或对象->数量。然后你使用任何一个字典来保存你正在查找的关系。这是时间/空间之间的标准权衡。

标签: python class dictionary for-loop


【解决方案1】:

使用列表解析和next() 可以让您只找到您要查找的项目的第一次出现,然后停止。在找到您要查找的密钥后打破 for 循环将实现相同的目标。两者都是 O(n),没有太多优化的空间。一个班轮将是

x = next((k for k in mars.inv.keys() if i in k.name), None)

【讨论】:

    【解决方案2】:

    我可能会将名称复制为字典的键并将其映射到其他信息的元组:

    {"Iron": (ir, 10500), "Gold": (gd, 800), "Silver": (sl, 6000}
    

    然后你可以通过mars.inv["Iron"] 得到(ir, 10500) 的元组,你可以从中提取任何你想要的数据。


    但请注意,这需要在名称上进行 精确 匹配。您当前正在使用in 进行检查,这将阻止任何优化。由于根据您的描述,您正在根据确切的名称进行查找(忽略大小写,因为这很容易解释),in 是不必要的。

    【讨论】:

      猜你喜欢
      • 2012-01-26
      • 1970-01-01
      • 2016-09-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-22
      • 2013-02-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多