【问题标题】:How to print values instead of memory addresses for my hashtable? Python如何为我的哈希表打印值而不是内存地址? Python
【发布时间】:2021-10-20 18:56:10
【问题描述】:

我正在将包数据从 csv 读取到我的哈希表,当我去打印数据以检查它是否被正确插入时,我得到了值的内存地址。它读取 packageID 并正确打印该部分。 对于目前将整个项目格式化为一个文件,我深表歉意。我是 Python 新手以及文件如何协同工作。当我将它们拆分为 Pycharm 中的单独文件时,我不知道正在执行什么,因为它的下拉菜单一次会运行一个文件(我的猜测)?

import csv
import math


####################################################################################################################

class hashtable:
    # Set initial capacity of the Hashtable to 40 and sets the buckets to empty.
    def __init__(self, initial_capacity=40):
        # initialize the hash table with empty bucket list entries.
        self.table = []
        for i in range(initial_capacity):
            self.table.append([])

    # Inserts new key:value pair into desired bucket.
    def insert(self, key, item):  # does both insert and update
        # get the bucket list where this item will go.
        bucket = hash(key) % len(self.table)
        bucket_list = self.table[bucket]
        key_value = [key, item]
        bucket_list.append(key_value)
        return True

    # Searches for the package using its packageID as the key and returns it if found.
    def search(self, key):
        # get the bucket list where this key would be.
        bucket = hash(key) % len(self.table)
        bucket_list = self.table[bucket]
        # print(bucket_list)

        # search for the key in the bucket list
        for kv in bucket_list:
            # print (key_value)
            if kv[0] == key:
                return kv[1]  # value
        return None

    # Removes a package with the matching key.
    def remove(self, key):
        # get the bucket list where this item will be removed from.
        bucket = hash(key) % len(self.table)
        bucket_list = self.table[bucket]

        # remove the item from the bucket list if it is present.
        for kv in bucket_list:
            # print (key_value)
            if kv[0] == key:
                bucket_list.remove([kv[0], kv[1]])


####################################################################################################################

class Package:
    def __init__(self, ID, Address, City, State, Zip, Deadline, Weight, Notes, Status, Deliverytime):
        self.packageID = ID
        self.packageAddress = Address
        self.packageCity = City
        self.packageState = State
        self.packageZip = Zip
        self.packageDeadline = Deadline
        self.packageWeight = Weight
        self.packageNotes = Notes
        self.packageStatus = Status
        self.deliveryTime = Deliverytime


#####################################################################################################################


def loadPackageData(fileName):
    with open(fileName) as Package_List:
        packageData = csv.reader(Package_List, delimiter=',')
        for package in packageData:
            pID = int(package[0])
            pAddress = package[1]
            pCity = package[2]
            pState = package[3]
            pZip = package[4]
            pDeadline = package[5]
            pWeight = package[6]
            pNotes = package[7]
            pStatus = "At hub"
            pDeliverytime = "00:00"

            #package object
            p = Package(pID, pAddress, pCity, pState, pZip, pDeadline, pWeight, pNotes, pStatus, pDeliverytime)
            #print (p)

            # insert into the hash table
            myHash.insert(pID, p)

# Hash table instance
myHash = hashtable()

# Load packages to Hashtable
loadPackageData('packageData.csv')

print("Packages from Hashtable:")
print(myHash.table)
# Fetch data from hashtable
#for i in range (len(myHash.table)+1):
#    print("Package: {}".format(myHash.search(i+1))) # 1 to 40 sent to myHash.search()

当 print(myHash.table) 被调用时,除了所有 40 个包之外,我得到的输出结构是这样的。

[[[40, <__main__.Package object at 0x000001E1489114C0>]], [[1, <__main__.Package object at 0x000001E148914220>]], [[2, <__main__.Package object at 0x000001E148911DF0>]], [[3, <__main__.Package object at 0x000001E148911D00>]]

我不明白如何在另一个帖子中提出与我的项目类似的问题,所以我现在在这里。非常感谢大家的帮助!

【问题讨论】:

  • 为您的 Package 类编写一个 __repr__() 方法,打印您想要的内容。
  • 这与哈希表无关。如果您只是打印一个包含Package 对象的变量,也会遇到同样的问题。
  • 为什么要实现自己的哈希表而不是只使用字典?
  • 为什么它的打印方式很重要?这就是您的 o 文本在打印时的表现方式。

标签: python hashtable memory-address


【解决方案1】:

您必须重写 __repr__ and __str__ 方法,以便类能够打印您需要的内容。

您可以通过其他方式添加自己的human_readable-like 属性

class PackageA:
  def __init__(self, ID, Address, City, State, Zip, Deadline, Weight, Notes, Status, Deliverytime):
    self.packageID = ID
    self.packageAddress = Address
    self.packageCity = City
    self.packageState = State
    self.packageZip = Zip
    self.packageDeadline = Deadline
    self.packageWeight = Weight
    self.packageNotes = Notes
    self.packageStatus = Status
    self.deliveryTime = Deliverytime

class PackageB:
  def __init__(self, ID, Address, City, State, Zip, Deadline, Weight, Notes, Status, Deliverytime):
    self.packageID = ID
    self.packageAddress = Address
    self.packageCity = City
    self.packageState = State
    self.packageZip = Zip     
    self.packageDeadline = Deadline
    self.packageWeight = Weight
    self.packageNotes = Notes
    self.packageStatus = Status
    self.deliveryTime = Deliverytime

  def __str__(self):
    return f'STR is <{self.packageID} {self.packageAddress} {self.packageCity} {self.packageState} {self.packageZip} {self.packageDeadline} {self.packageWeight} {self.packageNotes} {self.packageStatus} {self.deliveryTime}>'

  def __repr__(self):
    return f'REPR is <{self.packageID} {self.packageAddress} {self.packageCity} {self.packageState} {self.packageZip} {self.packageDeadline} {self.packageWeight} {self.packageNotes} {self.packageStatus} {self.deliveryTime}>'

  @property
  def human_readable(self):
    return f'Readable representation is <{self.packageID} {self.packageAddress} {self.packageCity} {self.packageState} {self.packageZip} {self.packageDeadline} {self.packageWeight} {self.packageNotes} {self.packageStatus} {self.deliveryTime}>'

packagesA = []
packagesB = []

for i in range(0,3):
  packagesA.append(PackageA(f"ID{i}", f"Address{i}", f"City{i}", f"State{i}", f"Zip{i}", f"Deadline{i}", f"Weight{i}", f"Notes{i}", f"Status{i}", f"Deliverytime{i}"))
  packagesB.append(PackageB(f"ID{i}", f"Address{i}", f"City{i}", f"State{i}", f"Zip{i}", f"Deadline{i}", f"Weight{i}", f"Notes{i}", f"Status{i}", f"Deliverytime{i}"))


print(packagesA)
print("--")
print(packagesB)
print("--")
print([str(x) for x in packagesB])
print("--")
print([x.human_readable for x in packagesB])

输出:

[<__main__.PackageA object at 0x104ca0710>, <__main__.PackageA object at 0x104ca0a90>, <__main__.PackageA object at 0x104ca0e10>]
--
[REPR is <ID0 Address0 City0 State0 Zip0 Deadline0 Weight0 Notes0 Status0 Deliverytime0>, REPR is <ID1 Address1 City1 State1 Zip1 Deadline1 Weight1 Notes1 Status1 Deliverytime1>, REPR is <ID2 Address2 City2 State2 Zip2 Deadline2 Weight2 Notes2 Status2 Deliverytime2>]
--
['STR is <ID0 Address0 City0 State0 Zip0 Deadline0 Weight0 Notes0 Status0 Deliverytime0>', 'STR is <ID1 Address1 City1 State1 Zip1 Deadline1 Weight1 Notes1 Status1 Deliverytime1>', 'STR is <ID2 Address2 City2 State2 Zip2 Deadline2 Weight2 Notes2 Status2 Deliverytime2>']
--
['Readeable representation is <ID0 Address0 City0 State0 Zip0 Deadline0 Weight0 Notes0 Status0 Deliverytime0>', 'Readeable representation is <ID1 Address1 City1 State1 Zip1 Deadline1 Weight1 Notes1 Status1 Deliverytime1>', 'Readeable representation is <ID2 Address2 City2 State2 Zip2 Deadline2 Weight2 Notes2 Status2 Deliverytime2>']

【讨论】:

    【解决方案2】:

    在这种情况下,它正在打印 python 对象默认 __repr__(),它打印 classname&lt;memory location&gt;。您可能想要编写一个自定义的__repr__(),它会返回一个字符串,其中包含您想要在那里显示的数据。

    所以在你的情况下,你可能想做这样的事情:

    class Package:
        def __init__(self, ID, Address, City, State, Zip, Deadline, Weight, Notes, Status, Deliverytime):
            self.packageID = ID
            self.packageAddress = Address
            self.packageCity = City
            self.packageState = State
            self.packageZip = Zip
            self.packageDeadline = Deadline
            self.packageWeight = Weight
            self.packageNotes = Notes
            self.packageStatus = Status
            self.deliveryTime = Deliverytime
        
        def __repr__(self):
            # Creates a list of lists where [value, attribute]
            attributes = [[getattr(self, attr), attr] for attr in dir(self) if not attr.startswith("__")]
    
            # Start result string with classname
            result = "Package("
    
            for attribute in attributes:
                result += f"{attribute[1]}= {attribute[0]},"
            
            result+=")"
            return result
    
    print(Package(1,1,1,1,1,1,1,1,1,1)) # prints Package(deliveryTime= 1,packageAddress= 1,packageCity= 1,packageDeadline= 1,packageID= 1,packageNotes= 1,packageState= 1,packageStatus= 1,packageWeight= 1,packageZip= 1,)
    

    这是一个非常快速和肮脏的实现,你可以清理得更快,做你想做的事,但基本上它会逐步遍历类并遍历每个非 dunder(以__ 开头)属性,然后创建类中每个属性的classname(attribute=value,) 形式的字符串。

    查看您的课程,您也可以使用dataclasses 模块,因为您有很多属性,但由于我不知道类型,我无法为您提供解决方案,或者使用namedtuple。所有这些都内置了__repr__()函数。

    【讨论】:

      【解决方案3】:

      在Package 类中,您将编写一个__repr__ 函数,该函数将返回您想要的字符串。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-02-26
        • 2011-07-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-18
        相关资源
        最近更新 更多