#1 楼
您的设计没有遵循最佳实践。当您使用
Library
时,您的__init__
类应该创建一个库,而不是一本书。所以我将代码分成两半,创建了两个类。一个用于书籍,另一个用于图书馆。
您不应该对
Library
上的数据进行突变。这是因为它是在类上而不是在实例上对其进行突变。因此,如果创建一个新实例,则它将与所有其他实例绑定。制作book类时。使用
collections.namedtuple
可以大大简化此操作。例如:Book = namedtuple('Book', 'name author ISBN price')
所以我将您的代码更改为:
from collections import namedtuple
class Library(object):
def __init__(self):
self.books = []
def addBook(self, book):
self.books.append(book)
def searchBookISBN(self, ISBN):
for book in self.books:
if book.ISBN == ISBN:
return book
def searchBookAuthor(self, author):
written_by_author = []
for book in self.books:
if book.author == author:
written_by_author.append(book)
return written_by_author
def searchUnderPrice(self, price):
books_under_price = []
for book in self.books:
if book.price < price:
books_under_price.append(book)
return books_under_price
Book = namedtuple('Book', 'name author ISBN price')
library = Library()
library.addBook(Book('Geometry', 'Jeff Potter', '0596805888', 22))
library.addBook(Book('Math', 'George Harr', '0594805888', 15))
library.addBook(Book('English', 'James Odd', '0596225888', 10))
library.addBook(Book('Physics', 'Jeff Potter', '0597884512', 18))
print(library.searchBookISBN('0594805888'))
print(library.searchBookAuthor('George Harr'))
print(library.searchUnderPrice(20))
之后,我建议:
您阅读并遵循PEP 8,以便您的代码更易于阅读。
您将学习列表理解
可以进一步改善您的代码,以:
class Library(object):
def __init__(self):
self.books = []
def add_book(self, book):
self.books.append(book)
def book_with_ISBN(self, ISBN):
for book in self.books:
if book.ISBN == ISBN:
return book
def books_by_author(self, author):
return [book for book in self.books if book.author == author]
def books_under_price(self, price):
return [book for book in self.books if book.price < price]
#2 楼
这是Peilonrayz出色答案的附录。根据您的图书馆规模的增长,可以线性搜索书籍以找到特定的作者或ISBN(甚至是价格较低的书籍)。很长一段时间(显然它会增长\ $ \ mathcal {O}(n)\ $)。
所以您可以为ISBN和周围的作者保留一本字典,以快速找到合适的书:
from collections import defaultdict
class Library(object):
def __init__(self):
self.books = []
self.index_from_author = defaultdict(list)
self.index_from_isbn = {}
def add_book(self, book):
self.books.append(book)
index = len(self.books) - 1
self.index_from_author[book.author].append(index)
self.index_from_isbn[book.ISBN] = index
def book_with_ISBN(self, ISBN):
return self.books[self.index_from_isbn[ISBN]]
def books_by_author(self, author):
return [self.books[i] for i in self.index_from_author[author]]
...
这是假定每个ISBN仅存在一本书(不是不合理的假设),但是一个作者可以拥有多本书(也是合理的)。 br />
请注意,如果您要从图书馆中删除一本书,则该代码还需要处理从这两个词典中删除它。棘手的。您可以使用线性时间,也可以将书堆放在堆中,堆按价格排序。然后,您可以将书插入正确的位置,并可以对所有低于某个价格的书进行二进制搜索。但这要涉及更多一点,我现在没有时间为此编写示例解决方案。
#3 楼
由于缺乏面向对象风格的想象力,因此实现存在问题。有了更多的经验,您将有更好的想法。 ;)OOP主要是关于对象的。您创建的内容看起来就像是图书馆。我不认为Book正在扩展Library。相反,(从我的角度来看)库包含许多Books。
建议该应用程序可以包含两个类。图书馆和书。
让我们迭代创建该应用程序。
第一次迭代为您提供对象
创建类包含名称,作者,ISBN,价格
创建类库,其中包含书籍集合(集合,列表)或数组
现在拥有的-您可以从图书馆中获取书籍(如果知道要购买哪本书)。
第二次迭代带来了新方法
想要的方法是
add books
,search for ISBN
和search by authors name
或finding lower priced books
。好吧,这些可能是不同集合上的其他功能。由于我的首选语言是Java,所以我只给出建议:
放在图书馆的图书集中之首
Add books
可以很好地用于地图(ISBN,书)search for ISBN
可以很好地用于MultiMap(作者名,书) 参数:名字和姓氏,甚至出生的年份。.
(价格,书)
第三次迭代将用于优化
基本上可以找到实现的更好想法。无需将Book添加到3个不同的馆藏中。相反,最好将Book添加到一个集合中并从不同的集合中进行查询。在bookMap上(以获取Book而不只是ISBN)。
我使用这些Maps的原因:
HashMap是
search for authors name
(又称即时),同时具有良好的哈希函数和大小。 TreeMap使用合理的
finding books with lower price
对键进行了排序,因此仅遍历书籍,直到可以解决问题为止。最后一步,我选择了最简单的情况。
评论
\ $ \ begingroup \ $
通过保留字典以通过ISBN或作者进行搜索来进行O(1)查找也很方便。
\ $ \ endgroup \ $
–地狱
17年11月24日在13:11
\ $ \ begingroup \ $
@Graipher是的,您可以随时提出答案。 🙂我觉得我们不知道如何使用代码,所以过早的优化可能不是一个好主意
\ $ \ endgroup \ $
– Peilonrayz
17年11月24日在13:21
\ $ \ begingroup \ $
完成。我同意过早的优化,但是总的来说,我希望图书馆有三本以上的书:)
\ $ \ endgroup \ $
–地狱
17年11月24日在13:55
\ $ \ begingroup \ $
@Graipher我也是,但是这听起来像是一个作业问题。里面只有四本书。因此,IMO的维护成本将超过速度收益。否则,我会完全同意,也对您的答案+1。
\ $ \ endgroup \ $
– Peilonrayz
17年11月24日14:18
\ $ \ begingroup \ $
您还可以使books_by_author和books_under_price生成器函数或返回filter()。
\ $ \ endgroup \ $
–理查德·诺伊曼(Richard Neumann)
17年11月24日14:29